Panduan untuk Pembina di Jawa

1. Pengenalan

Pembina adalah penjaga pintu reka bentuk berorientasikan objek .

Dalam tutorial ini, kita akan melihat bagaimana mereka bertindak sebagai satu lokasi untuk memulakan keadaan dalaman objek yang sedang dibuat.

Mari maju dan buat objek mudah yang mewakili akaun bank.

2. Menyiapkan Akaun Bank

Bayangkan bahawa kita perlu membuat kelas yang mewakili akaun bank. Ia akan mengandungi Nama, Tarikh Penciptaan dan Imbangan.

Juga, mari kita ganti kaedah toString untuk mencetak butiran ke konsol:

class BankAccount { String name; LocalDateTime opened; double balance; @Override public String toString() { return String.format("%s, %s, %f", this.name, this.opened.toString(), this.balance); } } 

Sekarang, kelas ini mengandungi semua bidang yang diperlukan untuk menyimpan maklumat mengenai akaun bank, tetapi belum mengandungi konstruktor.

Ini bermaksud bahawa jika kita membuat objek baru, nilai medan tidak akan diinisialisasi:

BankAccount account = new BankAccount(); account.toString(); 

Menjalankan kaedah toString di atas akan menghasilkan pengecualian kerana nama objek dan dibuka masih kosong :

java.lang.NullPointerException at com.baeldung.constructors.BankAccount.toString(BankAccount.java:12) at com.baeldung.constructors.ConstructorUnitTest .givenNoExplicitContructor_whenUsed_thenFails(ConstructorUnitTest.java:23) 

3. Pembina Tanpa Argumen

Mari perbaiki dengan konstruktor:

class BankAccount { public BankAccount() { this.name = ""; this.opened = LocalDateTime.now(); this.balance = 0.0d; } } 

Perhatikan beberapa perkara mengenai pembina yang baru sahaja kita tulis. Pertama, ia adalah kaedah, tetapi tidak mempunyai jenis pengembalian. Ini kerana konstruktor secara implisit mengembalikan jenis objek yang dihasilkannya. Memanggil BankAccount baru () sekarang akan memanggil pembangun di atas.

Kedua, tidak memerlukan hujah. Jenis konstruktor khas ini disebut pembina o-argumen .

Mengapa kita tidak memerlukannya untuk pertama kalinya? Ini kerana apabila kita tidak menulis konstruktor secara eksplisit, penyusun menambah pembina tanpa argumen lalai .

Inilah sebabnya mengapa kami dapat membina objek pada kali pertama, walaupun kami tidak menulis konstruktor secara eksplisit. Lalai, tidak ada pembina argumen yang hanya akan menetapkan semua ahli ke nilai lalai mereka.

Untuk objek, itu tidak sah, yang menyebabkan pengecualian yang kita lihat sebelumnya.

4. Pembina Parameter

Kini, manfaat sebenar pembina adalah mereka membantu kita mengekalkan enkapsulasi ketika menyuntikkan keadaan ke dalam objek.

Oleh itu, untuk melakukan sesuatu yang sangat berguna dengan akaun bank ini, kita perlu benar-benar dapat memasukkan beberapa nilai awal ke dalam objek.

Untuk melakukan itu, mari kita tulis konstruktor parameter , iaitu konstruktor yang mengambil beberapa argumen :

class BankAccount { public BankAccount() { ... } public BankAccount(String name, LocalDateTime opened, double balance) { this.name = name; this.opened = opened; this.balance = balance; } } 

Kini kami dapat melakukan sesuatu yang berguna dengan kelas BankAccount kami :

 LocalDateTime opened = LocalDateTime.of(2018, Month.JUNE, 29, 06, 30, 00); BankAccount account = new BankAccount("Tom", opened, 1000.0f); account.toString(); 

Perhatikan, bahawa kelas kita sekarang mempunyai 2 pembina. Pembina argumen eksplisit, dan pembina parameter.

Kita boleh membuat sebilangan besar pembina yang kita mahu, tetapi kita mungkin tidak mahu membuat terlalu banyak pembina. Ini akan sedikit membingungkan.

Sekiranya kita menemui terlalu banyak pembina dalam kod kita, beberapa Corak Reka Bentuk Penciptaan mungkin bermanfaat.

5. Pembina Salin

Pembina tidak perlu terhad kepada permulaan sahaja. Mereka juga dapat digunakan untuk membuat tingkah laku. Bayangkan bahawa kita perlu dapat membuat akaun baru dari yang ada.

Akaun baru harus mempunyai nama yang sama dengan akaun lama, tarikh penciptaan hari ini dan tanpa dana. Kita boleh melakukannya dengan menggunakan salinan konstruktor :

public BankAccount(BankAccount other) { this.name = other.name; this.opened = LocalDateTime.now(); this.balance = 0.0f; } 

Sekarang kita mempunyai tingkah laku berikut:

LocalDateTime opened = LocalDateTime.of(2018, Month.JUNE, 29, 06, 30, 00); BankAccount account = new BankAccount("Tim", opened, 1000.0f); BankAccount newAccount = new BankAccount(account); assertThat(account.getName()).isEqualTo(newAccount.getName()); assertThat(account.getOpened()).isNotEqualTo(newAccount.getOpened()); assertThat(newAccount.getBalance()).isEqualTo(0.0f); 

6. Pembina Berantai

Sudah tentu, kita mungkin dapat menyimpulkan beberapa parameter konstruktor atau memberikan beberapa nilai lalai.

Sebagai contoh, kita hanya boleh membuat akaun bank baru dengan nama sahaja.

Oleh itu, mari buat konstruktor dengan parameter nama dan berikan nilai lalai parameter lain:

public BankAccount(String name, LocalDateTime opened, double balance) { this.name = name; this.opened = opened; this.balance = balance; } public BankAccount(String name) { this(name, LocalDateTime.now(), 0.0f); }

Dengan kata kunci ini, kami memanggil pembina yang lain.

Kita harus ingat bahawa jika kita mahu membuat rangkaian konstruktor superclass, kita harus menggunakan super bukan ini .

Juga, ingat bahawa ungkapan ini atau super harus selalu menjadi pernyataan pertama.

7. Jenis Nilai

Penggunaan konstruktor yang menarik di Java adalah dalam pembuatan Objek Nilai . Objek nilai adalah objek yang tidak mengubah keadaan dalamannya setelah inisialisasi.

Maksudnya, objek itu tidak berubah . Kebolehubahan di Jawa agak bernuansa dan berhati-hati harus dibuat ketika membuat objek.

Mari maju dan buat kelas yang tidak berubah:

class Transaction { final BankAccount bankAccount; final LocalDateTime date; final double amount; public Transaction(BankAccount account, LocalDateTime date, double amount) { this.bankAccount = account; this.date = date; this.amount = amount; } } 

Perhatikan, bahawa kita sekarang menggunakan kata kunci terakhir ketika menentukan ahli kelas. Ini bermaksud bahawa setiap ahli tersebut hanya dapat diinisialisasi dalam pembina kelas. Mereka tidak dapat ditugaskan kemudian di dalam kaedah lain. Kita boleh membaca nilai-nilai itu, tetapi tidak mengubahnya.

Sekiranya kita membuat pelbagai pembina untuk kelas Transaksi , setiap pembina perlu menginisialisasi setiap pemboleh ubah akhir. Tidak melakukannya akan menyebabkan ralat penyusunan.

8. Kesimpulannya

Kami telah mengikuti pelbagai cara di mana pembina membina objek. Apabila digunakan secara bijaksana, konstruk membentuk blok bangunan asas reka bentuk Berorientasikan Objek di Jawa.

Seperti biasa, sampel kod boleh didapati di GitHub.