
new
และทุกอย่างก็พร้อม :) ที่นี่เราจะพูดถึงสิ่งที่เกิดขึ้นภายในคอมพิวเตอร์และเครื่อง Java เมื่อเราเขียน ตัวอย่างเช่น:
Cat cat = new Cat();
เราเคยพูดถึงเรื่องนี้มาก่อนแล้ว แต่ในกรณีที่เราจะเตือนคุณ:
- ขั้นแรกให้จัดสรรหน่วยความจำสำหรับจัดเก็บวัตถุ
- ถัดไป เครื่อง Java สร้างการอ้างอิงถึงวัตถุ (ในกรณีของเรา การอ้างอิงคือ Cat cat)
- สุดท้าย ตัวแปรจะเริ่มต้นและตัวสร้างถูกเรียก (เราจะดูรายละเอียดเพิ่มเติมเกี่ยวกับกระบวนการนี้)

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++;
}
}
คลาส นี้Truck
เป็นการนำรถบรรทุกมาใช้โดยมีช่องแสดงปี รุ่น และความเร็วสูงสุด ตอนนี้เราต้องการสร้างวัตถุดังกล่าว:
public class Main {
public static void main(String[] args) throws IOException {
Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
}
}
สำหรับเครื่อง Java กระบวนการจะมีลักษณะดังนี้:
-
สิ่งแรกที่เกิดขึ้นคือตัวแปรสแตติกของ
Vehicle
คลาสจะเริ่มต้น ใช่ ชั้นบอกว่าVehicle
ไม่ใช่Truck
ตัวแปรสแตติกจะเริ่มต้นก่อนที่จะเรียกคอนสตรัคเตอร์ และจะเริ่มต้นในคลาสพาเรนต์ มาลองตรวจสอบสิ่งนี้กัน เราตั้งค่าvehicleCounter
ฟิลด์ในVehicle
คลาสเท่ากับ 10 และพยายามแสดงทั้งในVehicle
และTruck
ตัวสร้าง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++; } }
เราจงใจใส่คำสั่ง println ที่จุดเริ่มต้นของ
Truck
ตัวสร้างเพื่อให้แน่ใจว่าฟิลด์ของรถบรรทุกยังไม่ได้เริ่มต้นเมื่อvehicleCounter
แสดงและนี่คือผลลัพธ์:
10 10
-
หลังจากเริ่มต้นตัวแปรสแตติกของคลาสพาเรนต์แล้ว ตัวแปรสแตติกของคลาสลูกจะถูกเตรียมใช้งาน ในกรณีของเรา นี่คือ
truckCounter
ฟิลด์ของTruck
คลาสลองทำการทดลองอีกครั้งโดยเราจะพยายามแสดงค่า
truckCounter
ภายในTruck
คอนสตรัคเตอร์ก่อนที่ฟิลด์อื่นๆ จะเริ่มต้น: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++; } }
อย่างที่คุณเห็น ค่า 10 ถูกกำหนดให้กับตัวแปรสแตติกของเราแล้วเมื่อ
Truck
คอนสตรัคเตอร์เริ่มทำงาน -
ยังไม่ถึงเวลาสำหรับผู้สร้าง! การเริ่มต้นตัวแปรยังคงดำเนินต่อไป ตัวแปรที่ไม่คงที่ของคลาสพาเรนต์เริ่มต้นที่สาม อย่างที่คุณเห็น การสืบทอดทำให้กระบวนการสร้างวัตถุซับซ้อนขึ้นอย่างมาก แต่คุณทำอะไรไม่ได้เลย: คุณเพียงแค่ต้องจดจำบางสิ่งในการเขียนโปรแกรม :)
ในการทดลอง เราสามารถกำหนดค่าเริ่มต้นให้กับ
description
ตัวแปรในVehicle
คลาส แล้วเปลี่ยนค่านั้นในคอนสตรัคเตอร์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; } }
ลองใช้
main()
วิธีการของเราเพื่อสร้างรถบรรทุก:public class Main { public static void main(String[] args) throws IOException { Truck truck = new Truck(2017, "Scania S 500 4x2", 220); } }
เราได้ผลลัพธ์ดังต่อไปนี้:
Initial value of the description field Vehicle
นี่เป็นการพิสูจน์ว่าเมื่อ
Vehicle
คอนสตรัคเตอร์เริ่มdescription
ฟิลด์ได้รับการกำหนดค่าแล้ว -
ในที่สุดก็ถึงเวลาสำหรับผู้สร้าง! แม่นยำยิ่งขึ้น ถึงเวลาแล้วสำหรับตัวสร้างคลาสพื้นฐาน มันถูกเรียกใช้ในขั้นตอนที่สี่ของกระบวนการสร้างวัตถุ
นอกจากนี้ยังง่ายต่อการตรวจสอบ ลองส่งออกสองบรรทัดไปยังคอนโซล: บรรทัดหนึ่งภายใน
Vehicle
ตัวสร้างคลาสพื้นฐาน และบรรทัดที่สองภายในTruck
ตัวสร้าง เราต้องแน่ใจว่าบรรทัดภายในVehicle
ปรากฏขึ้นก่อน: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++; }
เราจะใช้
main()
วิธีของเราและดูผลลัพธ์:Hello from the Vehicle constructor! Hello from the Truck constructor!
ยอดเยี่ยม. แสดงว่าเราคิดไม่ผิด :) ไปกันต่อ
-
ถึงเวลาเริ่มต้นฟิลด์ที่ไม่คงที่ของคลาสลูก นั่นคือ
Truck
คลาส ของเรา ฟิลด์ทันทีภายในคลาสที่กำลังสร้างอินสแตนซ์จะไม่เริ่มต้นจนกว่าจะถึงขั้นตอนที่ห้า! น่าแปลกใจ แต่ก็จริง :) อีกครั้ง เราจะทำการตรวจสอบง่ายๆ — เช่นเดียวกับคลาสพาเรนต์: เราจะกำหนดค่าเริ่มต้นให้กับตัวแปรmaxSpeed
และในTruck
คอนสตรัคเตอร์ เราจะตรวจสอบว่าค่านั้นถูกกำหนดก่อนที่คอนสตรัคเตอร์จะเริ่มทำงาน: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++; } }
เอาต์พุตคอนโซล:
Initial value of maxSpeed = 150
อย่างที่คุณเห็น เมื่อ
Truck
คอนสตรัคเตอร์เริ่มmaxSpeed
มีค่าเท่ากับ 150 แล้ว! -
คอนสตรัคเตอร์ของ
Truck
คลาสลูกเรียกว่าและเมื่อถึงจุดนี้สุดท้ายแล้ว ตัวสร้างของคลาสที่เรากำลังสร้างอินสแตนซ์จะถูกเรียก!
เฉพาะในขั้นตอนที่หกฟิลด์จะได้รับการกำหนดค่าที่เราส่งผ่านเป็นอาร์กิวเมนต์ไปยังรถบรรทุกของเรา
อย่างที่คุณเห็น การ "สร้าง" รถบรรทุก ซึ่งก็คือกระบวนการสร้างวัตถุนั้นไม่ง่ายเลย แต่ดูเหมือนว่าเราได้แยกมันออกเป็นส่วนที่เล็กที่สุดแล้ว :)

GO TO FULL VERSION