
new
và mọi thứ đã sẵn sàng :) Ở đây chúng ta sẽ nói về những gì xảy ra bên trong máy tính và máy Java khi chúng ta viết, chẳng hạn:
Cat cat = new Cat();
Chúng tôi đã nói về điều này trước đây, nhưng để đề phòng, chúng tôi sẽ nhắc bạn:
- Đầu tiên, bộ nhớ để lưu trữ đối tượng được cấp phát.
- Tiếp theo, máy Java tạo một tham chiếu đến đối tượng (trong trường hợp của chúng tôi, tham chiếu là Cat cat).
- Cuối cùng, các biến được khởi tạo và hàm tạo được gọi (chúng ta sẽ xem xét quá trình này chi tiết hơn).

public class Vehicle {
public static int vehicleCounter = 0;
private String description = "Vehicle";
public Vehicle() {
}
public String getDescription() {
return description;
}
}
public class Truck extends Vehicle {
private static int truckCounter = 0;
private int yearOfManufacture;
private String model;
private int maxSpeed;
public Truck(int yearOfManufacture, String model, int maxSpeed) {
this.yearOfManufacture = yearOfManufacture;
this.model = model;
this.maxSpeed = maxSpeed;
Vehicle.vehicleCounter++;
truckCounter++;
}
}
Lớp này Truck
là một triển khai của một chiếc xe tải với các trường đại diện cho năm, kiểu xe và tốc độ tối đa của nó. Bây giờ chúng tôi muốn tạo một đối tượng như vậy:
public class Main {
public static void main(String[] args) throws IOException {
Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
}
}
Đối với máy Java, quy trình sẽ như sau:
-
Điều đầu tiên xảy ra là các biến tĩnh của
Vehicle
lớp được khởi tạo . Vâng, tôi đã nóiVehicle
lớp học, không phảiTruck
. Các biến tĩnh được khởi tạo trước khi các hàm tạo được gọi và điều này bắt đầu trong lớp cha. Hãy thử kiểm chứng điều này. Chúng tôi đặtvehicleCounter
trường trongVehicle
lớp bằng 10 và cố gắng hiển thị nó trong cả hàm tạoVehicle
vàTruck
hàm tạo.public class Vehicle { public static int vehicleCounter = 10; private String description = "Vehicle"; public Vehicle() { System.out.println(vehicleCounter); } public String getDescription() { return description; } } public class Truck extends Vehicle { private static int truckCount = 0; private int yearOfManufacture; private String model; private int maxSpeed; public Truck(int yearOfManufacture, String model, int maxSpeed) { System.out.println(vehicleCounter); this.yearOfManufacture = yearOfManufacture; this.model = model; this.maxSpeed = maxSpeed; Vehicle.vehicleCounter++; truckCount++; } }
Chúng tôi cố tình đặt câu lệnh println ở đầu hàm
Truck
tạo để đảm bảo rằng các trường của xe tải chưa được khởi tạo khivehicleCounter
được hiển thị.Và đây là kết quả:
10 10
-
Sau khi các biến tĩnh của lớp cha được khởi tạo, các biến tĩnh của lớp con cũng được khởi tạo. Trong trường hợp của chúng ta, đây là
truckCounter
trường củaTruck
lớp.Hãy thực hiện một thử nghiệm khác, nơi chúng tôi sẽ cố gắng hiển thị giá trị của
truckCounter
bên trongTruck
hàm tạo trước khi các trường khác được khởi tạo:public class Truck extends Vehicle { private static int truckCounter = 10; private int yearOfManufacture; private String model; private int maxSpeed; public Truck(int yearOfManufacture, String model, int maxSpeed) { System.out.println(truckCounter); this.yearOfManufacture = yearOfManufacture; this.model = model; this.maxSpeed = maxSpeed; Vehicle.vehicleCounter++; truckCounter++; } }
Như bạn có thể thấy, giá trị 10 đã được gán cho biến tĩnh của chúng ta khi
Truck
hàm tạo bắt đầu. -
Vẫn chưa đến lúc cho các nhà xây dựng! Quá trình khởi tạo biến vẫn tiếp tục. Các biến không tĩnh của lớp cha được khởi tạo thứ ba. Như bạn có thể thấy, tính kế thừa làm phức tạp đáng kể quá trình tạo một đối tượng, nhưng bạn không thể làm gì với nó: Bạn chỉ cần ghi nhớ một số điều trong lập trình :)
Như một thử nghiệm, chúng ta có thể gán một số giá trị ban đầu cho
description
biến trongVehicle
lớp, sau đó thay đổi nó trong hàm tạo.public class Vehicle { public static int vehicleCounter = 10; private String description = "Initial value of the description field"; public Vehicle() { System.out.println(description); description = "Vehicle"; System.out.println(description); } public String getDescription() { return description; } }
Hãy chạy
main()
phương thức của chúng ta để tạo ra một chiếc xe tải:public class Main { public static void main(String[] args) throws IOException { Truck truck = new Truck(2017, "Scania S 500 4x2", 220); } }
Chúng tôi nhận được kết quả sau:
Initial value of the description field Vehicle
Điều này chứng tỏ rằng khi
Vehicle
hàm tạo bắt đầu,description
trường đã được gán một giá trị. -
Cuối cùng, đã đến lúc cho các nhà xây dựng! Chính xác hơn, đã đến lúc dành cho hàm tạo của lớp cơ sở. Nó được gọi trong bước thứ tư của quá trình tạo đối tượng.
Điều này cũng khá dễ kiểm chứng. Hãy thử xuất hai dòng ra bàn điều khiển: một dòng bên trong
Vehicle
hàm tạo của lớp cơ sở, dòng thứ hai bên trongTruck
hàm tạo. Chúng ta cần được thuyết phục rằng dòng bên trongVehicle
được hiển thị đầu tiên:public Vehicle() { System.out.println("Hello from the Vehicle constructor!"); } public Truck(int yearOfManufacture, String model, int maxSpeed) { System.out.println("Hello from the Truck constructor!"); this.yearOfManufacture = yearOfManufacture; this.model = model; this.maxSpeed = maxSpeed; Vehicle.vehicleCounter++; truckCounter++; }
Chúng ta sẽ chạy
main()
phương thức của mình và xem kết quả:Hello from the Vehicle constructor! Hello from the Truck constructor!
Xuất sắc. Điều đó có nghĩa là chúng ta không nhầm :) Let's going on.
-
Bây giờ là lúc khởi tạo các trường không tĩnh của lớp con, tức là
Truck
lớp của chúng ta. Các trường ngay trong lớp được khởi tạo không được khởi tạo cho đến bước thứ năm! Đáng ngạc nhiên, nhưng đúng :) Một lần nữa, chúng ta sẽ thực hiện một kiểm tra đơn giản — giống như với lớp cha: chúng ta sẽ nhập một số giá trị ban đầu cho biếnmaxSpeed
và trongTruck
hàm tạo, chúng ta sẽ kiểm tra xem giá trị đó đã được gán trước khi hàm tạo bắt đầu chưa:public class Truck extends Vehicle { private static int truckCounter = 10; private int yearOfManufacture; private String model; private int maxSpeed = 150; public Truck(int yearOfManufacture, String model, int maxSpeed) { System.out.println("Initial value of maxSpeed = " + this.maxSpeed); this.yearOfManufacture = yearOfManufacture; this.model = model; this.maxSpeed = maxSpeed; Vehicle.vehicleCounter++; truckCounter++; } }
Đầu ra bảng điều khiển:
Initial value of maxSpeed = 150
Như bạn có thể thấy, khi
Truck
hàm tạo bắt đầu,maxSpeed
nó đã bằng 150! -
Hàm tạo của
Truck
lớp con được gọi.Và chỉ tại thời điểm này, cuối cùng, hàm tạo của lớp mà chúng ta đang khởi tạo mới được gọi!
Chỉ trong bước thứ sáu, các trường sẽ được gán các giá trị mà chúng tôi chuyển làm đối số cho xe tải của mình.
Như bạn có thể thấy, việc "dựng" một chiếc xe tải, tức là quá trình tạo đối tượng, không hề đơn giản. Nhưng có vẻ như chúng tôi đã chia nó thành những phần nhỏ nhất :)

GO TO FULL VERSION