Chuỗi hàm tạo là quá trình gọi một loạt các hàm tạo trong cùng một lớp hoặc bởi các hàm tạo của lớp con. Trong lập trình Java, chuỗi hàm tạo thường xảy ra do quá trình Kế thừa. Khi chúng ta xâu chuỗi hàm tạo trong một chương trình Java, dòng đầu tiên của hàm tạo phải luôn bắt đầu bằng phương thức this[] hoặc super[] tùy theo loại chuỗi hàm tạo mà chúng ta muốn triển khai. Chúng ta sử dụng phương thức this[] để gọi một hàm tạo từ một hàm tạo bị quá tải khác trong cùng một lớp và phương thức super[] để gọi một hàm tạo của lớp cha ngay lập tức
Bây giờ, hãy xem cách chúng ta có thể triển khai chuỗi hàm tạo trong Java
Các cách để triển khai Java Constructor Chaining
Có hai cách để tạo chuỗi hàm tạo được thực hiện trong Java, hãy xem hai cách dưới đây
1. Chuỗi xây dựng trong cùng một lớp
Chúng tôi tạo một số hàm tạo với số lượng tham số khác nhau [hoặc với các kiểu dữ liệu khác nhau của tham số] trong cùng một lớp và tạo một chuỗi với các hàm tạo này bằng phương thức this[], chúng tôi sử dụng phương thức this[] để gọi một hàm tạo từ một hàm tạo khác . Hãy xem một ví dụ về Java để hiểu rõ hơn
Chương trình Java ví dụ
class Main { public static void main[String args[]] { Employee employee = new Employee[]; // calling the 1st constructor System.out.println["Employee Name: " + employee.getName[]]; System.out.println["Employee ID: " + employee.getEmpID[]]; } } class Employee{ private String name; private int empID; // 1st constructor public Employee[]{ this["NULL"]; // calling the 2nd constructor } // 2nd constructor public Employee[String name]{ this[name, 0]; // calling the 3rd constructor } // 3rd constructor public Employee[String name, int empID]{ // fully parameterized constructor this.name = name; this.empID = empID; } public String getName[]{ return name; } public int getEmpID[]{ return empID; } }
đầu ra
Employee Name: NULL Employee ID: 0
Giải trình
- Từ hình ảnh trên chúng ta có thể hiểu rằng khi chúng ta tạo một đối tượng employee của lớp Employee, nó đã gọi một hàm khởi tạo không có tham số vì chúng ta không truyền bất kỳ tham số nào trong khi khởi tạo đối tượng employee
- Trong hàm tạo đầu tiên, chúng tôi đã sử dụng this["NULL"];
- Trong hàm tạo thứ hai, chúng tôi đã sử dụng this[name, 0];
- Constructor thứ ba khởi tạo đối tượng employee với tên chứa NULL và empID chứa 0
- Chuỗi các hàm tạo gọi từ các hàm tạo khác này được gọi là chuỗi hàm tạo trong cùng một lớp
2. Constructor Chaining từ Parent/Base Class
Mục tiêu của hàm tạo của lớp con là gọi hàm tạo của lớp cha trước. Điều này đảm bảo rằng việc khởi tạo các trường hoặc biến thành viên của lớp cha được thực hiện như bước đầu tiên trong quá trình tạo đối tượng của lớp con. Trong Java, các chuỗi kế thừa có thể chứa bất kỳ số lượng lớp nào, mọi hàm tạo của lớp con gọi hàm tạo của lớp cha trực tiếp [sử dụng phương thức super[]] trong một chuỗi cho đến khi nó đạt đến lớp cấp cao nhất. Hãy xem một ví dụ về Java để hiểu rõ hơn
Chương trình Java ví dụ
class Main { public static void main[String args[]] { WagonR car1 = new WagonR["WagonR 2022", "Automobile", 4, 4, 5]; System.out.println["Vehicle name: " + car1.getName[]]; System.out.println["Vehicle type: " + car1.getType[]]; System.out.println["Car doors: " + car1.getDoors[]]; System.out.println["Car wheels: " + car1.getWheels[]]; System.out.println["WagonR seats: " + car1.getSeats[]]; } } class Vehicle{ private String name; private String type; public Vehicle[String name, String type] { this.name = name; this.type = type; System.out.println["Vehicle constructor invoked!"]; } public String getName[]{ return name; } public String getType[]{ return type; } } class Car extends Vehicle{ private int doors; private int wheels; public Car[String name, String type, int doors, int wheels]{ super[name, type]; // Vehicle class constructor is called this.doors = doors; this.wheels = wheels; System.out.println["Car constructor invoked!"]; } public int getDoors[]{ return doors; } public int getWheels[]{ return wheels; } } class WagonR extends Car{ private int seats; public WagonR[String name, String type, int doors, int wheels, int seats]{ super[name, type, doors, wheels]; // Car class constructor is called this.seats = seats; System.out.println["WagonR constructor invoked!"]; } public int getSeats[]{ return seats; } }
đầu ra
Vehicle constructor invoked! Car constructor invoked! WagonR constructor invoked! Vehicle Name: WagonR 2022 Vehicle type: Automobile Car doors: 4 Car wheels: 4 WagonR seats: 5
Giải trình
- Chúng tôi đã tạo một lớp WagonR mở rộng lớp Xe hơi cũng mở rộng lớp Xe, có các trường nhất định được xác định trong mỗi lớp
- Từ hình ảnh trên chúng ta có thể hiểu rằng khi chúng ta tạo một đối tượng car1 của lớp WagonR, nó đã gọi hàm tạo của lớp WagonR
- Trong hàm tạo lớp WagonR, chúng tôi đã sử dụng super[tên, loại, cửa, bánh xe];
- Trong hàm tạo của lớp Car, chúng ta đã sử dụng super[name, type];
- Hàm tạo của lớp Xe [Cấp cao nhất] là hàm tạo được thực thi đầy đủ đầu tiên và sau đó, phần còn lại của mã trong hàm tạo Car và WagonR được thực thi tương ứng. Loại chuỗi hàm tạo này giúp khởi tạo tất cả các trường liên quan đến một đối tượng trong một lần
Tại sao chúng ta cần Constructor Chaining?
- Nếu chúng ta muốn khởi tạo các đối tượng của một lớp với các loại hoặc số lượng tham số khác nhau, chúng ta yêu cầu các định nghĩa hàm tạo khác nhau trong lớp. Các hàm tạo khác nhau này có thể được thực hiện một cách hiệu quả bằng cách sử dụng chuỗi hàm tạo
- Chuỗi hàm tạo trong Java cho phép chúng tôi xác định các hàm tạo khác nhau cho từng tác vụ và kết nối chúng với các liên kết hoặc chuỗi để cải thiện chất lượng của mã
- Nếu chúng ta không xâu chuỗi các hàm tạo với nhau và một trong số chúng yêu cầu một tham số nhất định, thì chúng ta sẽ phải khởi tạo tham số đó hai lần trong mỗi hàm tạo
Quy tắc cho Constructor Chaining
Nếu chúng ta muốn sử dụng chuỗi hàm tạo trong Java, chúng ta phải tuân theo các hướng dẫn bên dưới
- Định nghĩa của hàm tạo phải luôn bắt đầu bằng phương thức this[] hoặc super[] làm câu lệnh ban đầu
- Nên có ít nhất một hàm tạo trong lớp không bao gồm phương thức this[]
- Chuỗi hàm tạo có thể được thực hiện theo bất kỳ trình tự nào
Hoạt động của Constructor Chaining trong Java
Trong Java, chuỗi hàm tạo xảy ra do quá trình kế thừa. Khi xử lý hàm tạo của lớp cha, hàm tạo của lớp con sẽ gọi hàm tạo của lớp cha trước. Điều này đảm bảo rằng các thành viên của lớp cha được khởi tạo ở bước đầu tiên khi một đối tượng của lớp con được khởi tạo. Mọi hàm tạo của lớp con gọi hàm tạo của lớp cha trực tiếp trong một chuỗi cho đến khi nó đạt đến lớp cấp cao nhất. Tuy nhiên, một hàm tạo không thể gọi nhiều hơn một hàm tạo
Để hiểu cách hoạt động của chuỗi hàm tạo, hãy xem xét sơ đồ sau
Constructor Gọi từ Constructor khác
Có hai phương pháp để gọi các hàm tạo
Sử dụng phương thức này[]
- Phương thức this[] được sử dụng để gọi một hàm tạo từ một hàm tạo khác trong cùng một lớp
- Phương thức this[] chỉ có thể được sử dụng bên trong hàm tạo
- Nó phải là câu lệnh đầu tiên với các đối số thích hợp trong hàm tạo
Sử dụng phương thức super[]
- Phương thức super[] được sử dụng để gọi hàm tạo cha trực tiếp từ hàm tạo của lớp con
- Phương thức super[] chỉ có thể được sử dụng bên trong hàm tạo
- super[] cũng phải là câu lệnh đầu tiên với các đối số phù hợp trong hàm tạo của lớp con
Ghi chú. Một hàm tạo có thể có lệnh gọi super[] hoặc this[] nhưng không bao giờ có cả hai
ví dụ
Chúng ta hãy xem thêm một số ví dụ về chuỗi hàm tạo thông qua các chương trình Java
Gọi Trình xây dựng lớp hiện tại
Nếu chúng ta muốn gọi hàm tạo của lớp hiện tại, chúng ta sử dụng phương thức this[] trong Java. phương thức this[] phải được sử dụng vì JVM không bao giờ thêm nó tự động như phương thức super[]. Dòng đầu tiên của hàm tạo phải bắt đầu bằng phương thức this[] nhưng bên trong một lớp phải có ít nhất một hàm tạo không chứa phương thức this[]. Hãy xem cú pháp và một ví dụ để hiểu nó tốt hơn
cú pháp
class class_name{ public class_name[]{ // constructor this[]; } }
Chương trình Java ví dụ
class Main{ public static void main[String args[]]{ BankAccount acc1 = new BankAccount[]; acc1.accountDetails[]; } } class BankAccount { private String accountNumber; private long balance; private String customerName; private String email; private String phoneNumber; // 1st constructor public BankAccount[]{ this["2872", 0]; // calls 2nd constructor System.out.println["1st constructor called!"]; } // 2nd constructor public BankAccount[String accountNumber, long balance] { this[accountNumber, balance, "NULL", "NULL", "NULL"]; // calls 3rd constructor System.out.println["2nd constructor called!"]; } // 3rd constructor public BankAccount[String accountNumber, long balance, String customerName, String email, String phoneNumber]{ this.accountNumber = accountNumber; this.balance = balance; this.customerName = customerName; this.email = email; this.phoneNumber = phoneNumber; System.out.println["3rd constructor called!"]; } public void accountDetails[]{ System.out.println["Account Details:" + "\nCustomer Name: " + this.customerName + "\nAccount Number: " + this.accountNumber + "\nBalance: " + this.balance + "\nEmail: " + this.email + "\nPhone Number: " + this.phoneNumber + "\n\n"]; } }
đầu ra
3rd constructor called! 2nd constructor called! 1st constructor called! Account Details: Customer Name: NULL Account Number: 2872 Balance: 0 Email: NULL Phone Number: NULL
Giải trình
- Từ hình ảnh trên chúng ta có thể hiểu rằng khi chúng ta tạo một đối tượng acc1 của lớp BankAccount, nó đã gọi một hàm tạo có tham số bằng 0 vì chúng ta không truyền bất kỳ tham số nào trong khi khởi tạo đối tượng acc1
- Trong hàm tạo đầu tiên, chúng tôi đã sử dụng this["2872", 0];
- Trong hàm tạo thứ hai, chúng tôi đã sử dụng this[accountNumber, balance, "NULL", "NULL", "NULL"];
- Hàm tạo thứ ba đã khởi tạo đối tượng acc1 với số tài khoản chứa 2872, số dư chứa 0, tên khách hàng, email và số điện thoại chứa NULL trong mỗi trường
- Chuỗi các hàm tạo gọi từ các hàm tạo khác này được gọi là chuỗi hàm tạo trong cùng một lớp
Gọi Constructor siêu hạng
cú pháp
class extends { public []{ // constructor super[]; } }
Chương trình Java ví dụ
________số 8_______đầu ra
Dog name: rex Dog weight: 21.5 Dog legs: 4 Dog coat: Silky
Giải trình
- Chúng tôi đã tạo một lớp Chó mở rộng lớp Động vật có các trường nhất định được xác định trong mỗi lớp
- Từ hình ảnh trên chúng ta có thể hiểu rằng khi chúng ta tạo một đối tượng dog của lớp Dog, nó đã gọi phương thức khởi tạo của lớp Dog với 4 tham số
- Trong hàm tạo của lớp Dog, chúng ta đã sử dụng super[name, weight];
- Hàm tạo của lớp Animal [Cấp cao nhất] được thực thi đầy đủ đầu tiên và sau đó, phần còn lại của mã trong hàm tạo Dog được thực thi và các trường còn lại được khởi tạo
Nếu chúng ta thay đổi thứ tự của các nhà xây dựng
Chúng ta có thể đạt được chuỗi hàm tạo theo bất kỳ thứ tự nào, ngay cả khi chúng ta thay đổi thứ tự gọi hàm tạo trong chương trình java, nó vẫn sẽ đạt được chuỗi hàm tạo. Chúng ta hãy xem một ví dụ Java để hiểu tương tự
Chương trình Java ví dụ
0Employee Name: NULL Employee ID: 0
đầu ra
1Employee Name: NULL Employee ID: 0
Giải trình
- Trong ví dụ này, chúng tôi chỉ thay đổi thứ tự của các hàm tạo mà chúng được gọi, đôi khi điều này có thể không có ý nghĩa hoặc hiệu quả, nhưng đây là một cách để chỉ ra rằng các hàm tạo có thể được xâu chuỗi theo bất kỳ trình tự nào
- Từ hình ảnh trên chúng ta có thể hiểu rằng khi chúng ta tạo một đối tượng s1 của lớp Student, nó đã gọi một hàm tạo có hai tham số vì chúng ta đã truyền hai tham số trong khi khởi tạo đối tượng s1
- Hàm tạo thứ ba trước tiên gọi hàm tạo thứ hai gọi hàm tạo thứ nhất
- Trong hàm tạo đầu tiên, chúng tôi chỉ in một thông báo trong bảng điều khiển đầu ra. Bây giờ, điều khiển chuyển sang hàm tạo thứ hai
- Trong hàm tạo thứ hai cũng vậy, chúng tôi chỉ in một thông báo trong bảng điều khiển đầu ra và điều khiển chuyển sang hàm tạo thứ ba
- Trong hàm tạo thứ ba, chúng tôi đã khởi tạo trường tên và số cuộn cho đối tượng s1 và in một thông báo trên màn hình
Một phương pháp thay thế chuỗi xây dựng bằng cách sử dụng khối khởi tạo
Chúng ta có thể bao gồm một số mã cụ thể trong khối init để đảm bảo rằng mã này được thực thi với các hàm tạo. Bất cứ khi nào chúng ta tạo một thể hiện của một lớp, khối init luôn chạy trước mã hàm tạo