Konstruktor (constructor) adalah prosedur khusus yang dijalankan otomatis ketika sebuah objek dibuat dengan New, sehingga objek tidak pernah berada dalam keadaan kosong yang tak terencana. Topik ini membahas deklarasi Sub New tanpa parameter dan berparameter, overloading konstruktor untuk beberapa cara pembuatan objek, perantaraan pemanggilan antar konstruktor dengan Me.New dan MyBase.New, serta inisialisasi objek dalam satu ekspresi dengan With. Contoh yang dijalankan adalah kelas CatatanPengeluaran yang menyediakan empat cara pembuatan objek berbeda.
Sub New sebagai konstruktor#
Konstruktor pada VB.NET dituliskan sebagai prosedur Sub New di dalam kelas. Prosedur ini tidak memiliki klausa As karena memang tidak mengembalikan nilai, dan prosedurnya dipanggil oleh runtime secara otomatis ketika operator New dieksekusi. Tugas utamanya adalah menyiapkan keadaan awal objek, misalnya mengisi field dengan nilai bawaan, memvalidasi data pembuka, atau menyiapkan objek pendamping. Tanpa konstruktor, keadaan awal objek sepenuhnya mengikuti nilai bawaan field, yaitu 0 untuk angka dan Nothing untuk teks, yang sering bukan keadaan yang diinginkan.
Selisihnya dengan prosedur biasa terletak pada waktunya. Prosedur biasa dipanggil dari kode lain sesuai kebutuhan, sedangkan konstruktor berjalan sekali pada saat instansiasi, sebelum objek digunakan. Karena itu pula logika di dalam konstruktor sebaiknya dijaga tetap ringkas, yaitu cukup untuk menyiapkan keadaan awal yang sah dan tidak untuk pekerjaan panjang seperti membaca berkas besar.
Tempat deklarasi konstruktor ada di dalam badan kelas, umumnya setelah daftar field dan properti serta sebelum metode-metode lainnya. Namanya selalu New, dan overloading-nya dibedakan hanya oleh daftar parameternya. Karena deklarasinya menggunakan kata kunci Sub, konstruktor tidak pernah mengembalikan nilai, sehingga penyiapan yang hasilnya perlu dikirim pemanggil memang bukan tugas konstruktor.
Konstruktor tanpa parameter dan overloading#
Kelas CatatanPengeluaran berikut menyediakan tiga konstruktor dengan daftar parameter yang berbeda. Pola menyediakan lebih dari satu tanda tangan untuk nama prosedur yang sama disebut overloading, dan aturannya berlaku juga untuk konstruktor. Ketiga konstruktor dijalankan dalam satu program untuk memperlihatkan keadaan awal yang berbeda tiap objeknya.
Class CatatanPengeluaran
Public Property Keterangan As String
Public Property Jumlah As Integer
Public Property Kategori As String
' konstruktor tanpa parameter memberi nilai bawaan
Public Sub New()
Keterangan = "Belanja harian"
Jumlah = 0
Kategori = "Umum"
End Sub
' overloading: konstruktor dengan satu parameter
Public Sub New(keterangan As String)
Me.New()
Me.Keterangan = keterangan
End Sub
' overloading: konstruktor dengan dua parameter
Public Sub New(keterangan As String, jumlah As Integer)
Me.New()
Me.Keterangan = keterangan
Me.Jumlah = jumlah
End Sub
Public Sub Tampilkan()
Console.WriteLine($"{Keterangan}: {Jumlah} ({Kategori})")
End Sub
End Class
Module Program
Sub Main()
Dim catatanSatu As New CatatanPengeluaran()
Dim catatanDua As New CatatanPengeluaran("Tiket kereta")
Dim catatanTiga As New CatatanPengeluaran("Buku catatan", 24)
catatanSatu.Tampilkan()
catatanDua.Tampilkan()
catatanTiga.Tampilkan()
' inisialisasi objek dengan With: penugasan properti pada satu ekspresi
Dim catatanEmpat As New CatatanPengeluaran() With {.Keterangan = "Kopi", .Jumlah = 10, .Kategori = "Konsumsi"}
catatanEmpat.Tampilkan()
End Sub
End ModuleBelanja harian: 0 (Umum)
Tiket kereta: 0 (Umum)
Buku catatan: 24 (Umum)
Kopi: 10 (Konsumsi)Keluaran memperlihatkan empat keadaan awal yang berbeda dari satu kelas. Objek pertama dibuat dengan konstruktor tanpa parameter sehingga seluruh nilainya bawaan, objek kedua dan ketiga dengan konstruktor berparameter, dan objek keempat dengan konstruktor tanpa parameter yang disusul penugasan properti melalui With. Compiler memilih konstruktor yang dipanggil dengan mencocokkan jumlah dan tipe argumennya, sehingga New CatatanPengeluaran("Tiket kereta") jatuh ke konstruktor satu parameter tanpa perintah tambahan apa pun.
Dua baris pada contoh perlu dibaca dengan saksama. Pernyataan Me.New() di awal konstruktor berparameter meneruskan pekerjaan ke konstruktor tanpa parameter terlebih dahulu, sehingga nilai bawaan seperti Kategori = "Umum" tetap terisi tanpa ditulis ulang. Pernyataan Me.Keterangan = keterangan menggunakan awalan Me karena parameter keterangan bentrok dengan nama properti Keterangan yang tidak dibedakan huruf besar-kecilnya pada VB.NET, dan tanpa awalan itu penugasan hanya menyentuh parameter semata.
Rantai konstruktor dan MyBase.New#
Perantaraan antar konstruktor diatur dengan dua kata kunci. Me.New() memanggil konstruktor lain pada kelas yang sama dan hanya boleh dituliskan sebagai pernyataan pertama konstruktor, sehingga rantai pembentukan objeknya selalu berurutan. Penggunaan ini mencegah duplikasi, karena penyiapan umum cukup ada pada satu konstruktor dan konstruktor lainnya menambahkan bagiannya saja.
Pada kelas turunan, perantaraan dilakukan dengan MyBase.New() yang memanggil konstruktor kelas induk. Pernyataan ini juga wajib berada di awal apabila dituliskan secara eksplisit, dan apabila tidak dituliskan, compiler menyisipkan pemanggilan MyBase.New() tanpa argumen secara otomatis. Fragment berikut memperlihatkan bentuk eksplisitnya pada kelas CatatanPenting yang mewarisi CatatanPengeluaran.
' tidak-dijalankan
Class CatatanPenting
Inherits CatatanPengeluaran
Public Sub New(keterangan As String, jumlah As Integer)
MyBase.New(keterangan, jumlah) ' meneruskan argumen ke konstruktor kelas induk
Kategori = "Prioritas" ' kelanjutan penyiapan khusus kelas turunan
End Sub
End ClassUrutan eksekusi pada fragment tersebut pasti. Konstruktor induk selesai terlebih dahulu, kemudian baris-baris badan konstruktor turunan baru dijalankan. Urutan ini menjamin seluruh keadaan milik kelas induk sudah siap ketika turunan mulai menambahkan penyiapannya sendiri, sehingga field dan properti warisan dapat digunakan tanpa pemeriksaan tambahan. Rantai yang sama berlaku berjenjang pada pohon pewarisan yang lebih dalam, karena setiap induk juga memanggil induknya sendiri.
Inisialisasi objek dengan With#
Selain konstruktor berparameter, VB.NET menyediakan inisialisasi objek (object initializer) yang menugaskan properti sejak baris pembuatannya. Bentuknya New Kelas() With {.Properti = nilai, ...} dalam satu ekspresi, sehingga objek yang diisi banyak properti tidak lagi menuntut satu pernyataan penugasan per properti. Objek catatanEmpat pada program menggunakan bentuk ini dan hasilnya sama dengan membuat objek terlebih dahulu lalu menugaskan tiga properti satu per satu.
Inisialisasi With bekerja pada properti, bukan pada parameter konstruktor, sehingga With tidak menggantikan konstruktor berparameter melainkan melengkapinya. Properti otomatis seperti Keterangan, Jumlah, dan Kategori menjadi sasaran yang paling tepat, karena ketiganya memang dirancang untuk ditugaskan dari luar. Untuk kelas yang keadaannya wajib lengkap sejak awal, konstruktor berparameter tetap menjadi pilihan yang lebih tegas karena compiler menuntut argumennya, sedangkan With membiarkan properti yang terlewat bernilai bawaan.
Kesalahan umum#
Kesalahan pertama adalah mengharapkan konstruktor tanpa parameter tetap tersedia setelah menambahkan Sub New berparameter. Pesan errornya menyatakan tidak ada New yang menerima argumen sesuai pemanggilan, dan perbaikannya adalah mendeklarasikan Sub New() eksplisit apabila bentuk tanpa argumen memang masih diperlukan. Kebiasaan yang lebih aman adalah menuliskan kedua bentuknya sejak awal apabila pemanggilan tanpa argumen memang dianjurkan.
Kesalahan kedua adalah menugaskan parameter yang namanya sama dengan properti, misalnya Keterangan = keterangan di dalam Sub New(keterangan As String). Penugasan itu sah menurut compiler tetapi hanya mengubah parameter, sehingga properti tidak pernah terisi dan keadaan bawaannya menetap. Perbaikannya adalah menggunakan awalan Me. pada sisi properti, sebagaimana Me.Keterangan = keterangan pada contoh, atau memberi nama parameter yang berbeda.
Kesalahan ketiga adalah menyediakan dua konstruktor dengan daftar parameter yang sama persis. Overloading menuntut tanda tangan yang berbeda, baik dari jumlah, tipe, maupun urutan parameternya, dan dua Sub New yang identik ditolak compiler karena pemanggilnya tidak dapat dibedakan. Apabila kedua konstruktor hanya berbeda pada kegunaannya, satu di antaranya digabungkan atau parameternya diperluas agar tanda tangannya benar-benar berbeda.
Ringkasan#
Sub Newadalah konstruktor yang dijalankan otomatis olehNewuntuk menyiapkan keadaan awal objek sebelum objek digunakan.- Beberapa konstruktor dengan daftar parameter berbeda dapat disediakan dengan overloading, dan perantaraan antar konstruktor menggunakan
Me.New()pada kelas yang sama sertaMyBase.New()pada kelas turunan. - Inisialisasi objek
New ... With {...}menugaskan properti dalam satu ekspresi dan melengkapi, bukan menggantikan, konstruktor berparameter.
Referensi#
- Object Lifetime: How Objects Are Created and Destroyed — Microsoft Learn — Siklus hidup objek dan peran konstruktor saat objek dibuat.
- Object Initializers: Named and Anonymous Types — Microsoft Learn
— Inisialisasi objek dengan
Withpada satu ekspresi. - Class Statement — Microsoft Learn — Konteks deklarasi anggota kelas, termasuk konstruktor.
- New Operator — Microsoft Learn
— Operator
Newyang memicu pembentukan objek dan pemanggilan konstruktor.