Konstruktor

Konstruktor dengan parameter, overloading konstruktor, dan inisialisasi objek.

Daftar isi

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.

vb Program.vb
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 Module
text Keluaran
Belanja 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.

vb Contoh: konstruktor turunan meneruskan argumen ke induk
' 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 Class

Urutan 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 New adalah konstruktor yang dijalankan otomatis oleh New untuk 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 serta MyBase.New() pada kelas turunan.
  • Inisialisasi objek New ... With {...} menugaskan properti dalam satu ekspresi dan melengkapi, bukan menggantikan, konstruktor berparameter.

Referensi#