Pendaftaran anggota perpustakaan di dunia nyata datang dalam berbagai bentuk: ada yang mengisi semua data lengkap, ada yang baru mengisi nama saja, dan petugas melengkapi sisanya belakangan. Bila class hanya menyediakan satu constructor berparameter penuh, pemanggil dengan data setengah jadi terpaksa mengarang nilai tempelan — atau kembali ke pola lama menciptakan object kosong lalu mengisi field manual. Java mengatasi kekakuan ini dengan constructor overloading: satu class boleh memiliki banyak constructor selama daftar parameternya berbeda. Pada Chapter ini kita pelajari cara kerja pemilihan constructor oleh compiler, lalu teknik delegasi this(...) yang membuat para constructor bekerja sama alih-alih mengulang kode.
Satu Class Banyak Bentuk Penciptaan #
Overloading constructor mengikuti aturan yang sama dengan overloading method: beberapa constructor berbagi satu nama (tentu saja, karena nama constructor wajib sama dengan nama class), tetapi jumlah, urutan, atau tipe parameternya harus berbeda. Compiler memilih constructor yang paling cocok dengan argumen pada saat kompilasi — keputusan ini murni analisis statis, tidak ada peran JVM di dalamnya. Bila dua constructor memiliki daftar parameter yang identik, compiler menolak keduanya; bila tidak ada satu pun yang cocok, compiler melaporkan galat cannot be applied to given types yang sudah kita jumpai pada Chapter sebelumnya.
Class AnggotaPerpustakaan berikut menyediakan tiga pintu pendaftaran. Constructor paling lengkap menerima nama, kota, dan kuota pinjam; dua constructor lainnya menerima data lebih sedikit dan mengisi kekurangannya dengan nilai bawaan:
class AnggotaPerpustakaan {
String nama;
String kota;
int maksimumPinjam;
AnggotaPerpustakaan(String nama, String kota, int maksimumPinjam) {
this.nama = nama;
this.kota = kota;
this.maksimumPinjam = maksimumPinjam;
System.out.println("[lengkap] " + nama + " | " + kota + " | kuota " + maksimumPinjam);
}
AnggotaPerpustakaan(String nama, String kota) {
this(nama, kota, 3);
System.out.println("[nama+kota] delegasi selesai");
}
AnggotaPerpustakaan(String nama) {
this(nama, "Tidak tercatat");
System.out.println("[nama saja] delegasi selesai");
}
void tampilkanProfil() {
System.out.println(nama + " dari " + kota
+ " dapat meminjam " + maksimumPinjam + " buku");
}
}Program pemanggil berikut mendaftarkan tiga anggota lewat tiga pintu yang berbeda:
public class AplikasiPendaftaran {
public static void main(String[] args) {
System.out.println("== pendaftaran 1 ==");
AnggotaPerpustakaan dewi = new AnggotaPerpustakaan("Dewi Lestari", "Jakarta", 5);
dewi.tampilkanProfil();
System.out.println("== pendaftaran 2 ==");
AnggotaPerpustakaan budi = new AnggotaPerpustakaan("Budi Santoso", "Surabaya");
budi.tampilkanProfil();
System.out.println("== pendaftaran 3 ==");
AnggotaPerpustakaan siti = new AnggotaPerpustakaan("Siti Rahmawati");
siti.tampilkanProfil();
}
}Output yang Dihasilkan:
== pendaftaran 1 ==
[lengkap] Dewi Lestari | Jakarta | kuota 5
Dewi Lestari dari Jakarta dapat meminjam 5 buku
== pendaftaran 2 ==
[lengkap] Budi Santoso | Surabaya | kuota 3
[nama+kota] delegasi selesai
Budi Santoso dari Surabaya dapat meminjam 3 buku
== pendaftaran 3 ==
[lengkap] Siti Rahmawati | Tidak tercatat | kuota 3
[nama+kota] delegasi selesai
[nama saja] delegasi selesai
Siti Rahmawati dari Tidak tercatat dapat meminjam 3 bukuKetiga object lahir dengan state penuh meskipun datanya datang tidak lengkap — kuota 3 dan kota "Tidak tercatat" terisi otomatis sebagai nilai bawaan. Mari kita bedah bagian-bagian kuncinya:
- Baris 5-11 (
AnggotaPerpustakaan(String nama, String kota, int maksimumPinjam)): constructor utama — satu-satunya yang benar-benar menulis field. Seluruh kebijakan inisialisasi terkumpul di satu tempat. - Baris 13-16 (
AnggotaPerpustakaan(String nama, String kota)): badannya hanya satu pernyataanthis(nama, kota, 3). Ekspresi ini memanggil constructor tiga-argumen di class yang sama, menambahkan nilai bawaan3untuk kuota — mirip caranewmemilih constructor, tetapi dari dalam class sendiri. - Baris 18-21 (
AnggotaPerpustakaan(String nama)): berantai satu tingkat lebih jauh — constructor satu-argumen mendelegasikan ke constructor dua-argumen, yang pada gilirannya mendelegasikan ke constructor utama. Nilai bawaan"Tidak tercatat"disuntikkan di sini. - Baris 12 pada
AplikasiPendaftaran.java(new AnggotaPerpustakaan("Siti Rahmawati")): compiler mencocokkan satu argumenStringdengan daftar parameter(String)dan memilih constructor paling ringkas. Tidak ada konversi atau tebakan runtime yang terlibat.
Delegasi dengan this() #
Urutan baris pada output pendaftaran 3 adalah bukti menarik cara delegasi bekerja: baris [lengkap] tercetak duluan, disusul [nama+kota], terakhir [nama saja]. Penjelasannya, pernyataan this(...) wajib menjadi pernyataan pertama dalam badan constructor. Akibatnya, ketika constructor satu-argumen mendelegasikan, seluruh pekerjaan constructor tujuan — termasuk delegasi yang dilakukan constructor tujuan itu sendiri — selesai lebih dulu, sebelum pernyataan sisanya berjalan. Delegasi berjalan dari ujung rantai ke pangkal rantai, lalu kode sisanya berjalan mundur ke arah pemanggil.
Dua aturan menjaga mekanisme ini tetap sehat. Pertama, this(...) hanya boleh muncul sekali dan harus di baris pertama — karenanya constructor tidak bisa sekaligus memanggil this(...) dan super(...) (pembahasan super(...) menunggu Chapter Keyword super). Kedua, rantai delegasi tidak boleh melingkar: constructor yang akhirnya memanggil dirinya sendiri, langsung maupun tidak langsung, ditolak compiler dengan pesan recursive constructor invocation.
Rangkaian this(nama, kota, 3) yang kita pakai berulang kali sepanjang Chapter ini sebenarnya adalah penggunaan istimewa dari kata kunci this: constructor memanggil constructor lain pada object yang sama. Kata kunci this punya dua wajah lain yang sama pentingnya — merujuk field yang tertutup parameter, dan mengirim object aktif sebagai argumen. Ketiganya kita bedah pada Chapter berikutnya.
Referensi #
- Java Language Specification — Chapter 8: Classes
- Oracle: dev.java — Object-Oriented Programming
- API java.base — java.lang.Object
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
AnggotaPerpustakaan.java
Unduh berkasclass AnggotaPerpustakaan {
String nama;
String kota;
int maksimumPinjam;
AnggotaPerpustakaan(String nama, String kota, int maksimumPinjam) {
this.nama = nama;
this.kota = kota;
this.maksimumPinjam = maksimumPinjam;
System.out.println("[lengkap] " + nama + " | " + kota + " | kuota " + maksimumPinjam);
}
AnggotaPerpustakaan(String nama, String kota) {
this(nama, kota, 3);
System.out.println("[nama+kota] delegasi selesai");
}
AnggotaPerpustakaan(String nama) {
this(nama, "Tidak tercatat");
System.out.println("[nama saja] delegasi selesai");
}
void tampilkanProfil() {
System.out.println(nama + " dari " + kota
+ " dapat meminjam " + maksimumPinjam + " buku");
}
}
AplikasiPendaftaran.java
Unduh berkaspublic class AplikasiPendaftaran {
public static void main(String[] args) {
System.out.println("== pendaftaran 1 ==");
AnggotaPerpustakaan dewi = new AnggotaPerpustakaan("Dewi Lestari", "Jakarta", 5);
dewi.tampilkanProfil();
System.out.println("== pendaftaran 2 ==");
AnggotaPerpustakaan budi = new AnggotaPerpustakaan("Budi Santoso", "Surabaya");
budi.tampilkanProfil();
System.out.println("== pendaftaran 3 ==");
AnggotaPerpustakaan siti = new AnggotaPerpustakaan("Siti Rahmawati");
siti.tampilkanProfil();
}
}