Animal
(สัตว์):
public class Animal {
String name;
int age;
}
เราสามารถสร้างมันขึ้นมาได้ เช่น คลาสสืบทอด 2 คลาส - Cat
และDog
. ทำได้โดยใช้คำextends
หลัก
public class Cat extends Animal {
}
public class Dog extends Animal {
}
สิ่งนี้อาจเป็นประโยชน์สำหรับเราในอนาคต เช่น ถ้างานคือจับหนู เราก็จะสร้างวัตถุขึ้นมาในCat
โปรแกรม หากงานคือการวิ่งตามแท่งไม้ เราก็ใช้วัตถุDog
นั้น และถ้าเราสร้างโปรแกรมจำลองคลินิกสัตวแพทย์ขึ้นมาก็จะได้ผลในชั้นเรียนAnimal
(สามารถรักษาได้ทั้งสุนัขและแมว) เป็นสิ่งสำคัญมากที่ต้องจำไว้ในอนาคตว่าเมื่อสร้างวัตถุ ตัวสร้างของคลาสฐานจะถูกเรียก ก่อนและเฉพาะจากนั้นจึงเรียกตัวสร้างของคลาสเองซึ่งเป็นวัตถุที่เรากำลังสร้างเท่านั้นจึงจะถูกเรียก นั่นคือเมื่อสร้างอ็อบเจ็กต์Cat
ตัวสร้างคลาสจะทำงานก่อน จากนั้นจึงสร้างเฉพาะตัว สร้างAnimal
เท่านั้น Cat
เพื่อให้แน่ใจในสิ่งนี้ ให้เพิ่มตัวสร้างCat
และAnimal
ส่งออกไปยังคอนโซล
public class Animal {
public Animal() {
System.out.println("Animal constructor completed");
}
}
public class Cat extends Animal {
public Cat() {
System.out.println("The constructor Cat worked!");
}
public static void main(String[] args) {
Cat cat = new Cat();
}
}
เอาต์พุตคอนโซล:
Отработал конструктор Animal
Отработал конструктор Cat!
แท้จริงแล้วมันทำงานอย่างไร! มีไว้เพื่ออะไร? ตัวอย่างเช่น เพื่อหลีกเลี่ยงไม่ให้ฟิลด์ทั่วไปของสองคลาสซ้ำกัน ตัวอย่างเช่น สัตว์ทุกตัวมีหัวใจและสมอง แต่ไม่ใช่สัตว์ทุกตัวที่มีหาง เราสามารถประกาศฟิลด์ที่เหมือนกันสำหรับสัตว์ทุกตัวbrain
ในheart
คลาสแม่Animal
และฟิลด์tail
ในคลาสCat
ย่อย ตอนนี้เราจะสร้าง Constructor สำหรับคลาสCat
โดยเราจะผ่านทั้ง 3 ฟิลด์
public class Cat extends Animal {
String tail;
public Cat(String brain, String heart, String tail) {
this.brain = brain;
this.heart = heart;
this.tail = tail;
}
public static void main(String[] args) {
Cat cat = new Cat("Brain", "Heart", "Tail");
}
}
ใส่ใจ:ตัวสร้างทำงานได้สำเร็จแม้ว่าคลาสCat
จะไม่มีฟิลด์brain
และheart
. Animal
ฟิลด์เหล่านี้ถูก " ดึงขึ้นมา" จากคลาสพื้นฐาน คลาสลูกหลานสามารถเข้าถึงฟิลด์ของคลาสพื้นฐานได้ ดังนั้นจึงCat
มองเห็นได้ในคลาสของเรา ดังนั้นเราจึงไม่จำเป็นCat
ต้องทำซ้ำฟิลด์เหล่านี้ในชั้นเรียน - เราสามารถนำมาจากชั้นเรียนAnimal
ได้ ยิ่งไปกว่านั้น เราสามารถเรียก Constructor ของคลาสพื้นฐานได้อย่างชัดเจนใน Constructor ของคลาสลูกหลาน คลาสพื้นฐานเรียกอีกอย่างว่า “ ซูเปอร์คลาสsuper
” ซึ่งเป็นสาเหตุที่ Java ใช้คีย์เวิร์ด ในตัวอย่างก่อนหน้านี้
public Cat(String brain, String heart, String tail) {
this.brain = brain;
this.heart = heart;
this.tail = tail;
}
เราแยกแต่ละฟิลด์ที่อยู่ในคลาสหลักของเรา ที่จริงแล้วคุณไม่จำเป็นต้องทำเช่นนี้ ก็เพียงพอแล้วที่จะเรียกตัวสร้างของคลาสพาเรนต์และส่งพารามิเตอร์ที่จำเป็น:
public class Animal {
String brain;
String heart;
public Animal(String brain, String heart) {
this.brain = brain;
this.heart = heart;
}
public class Cat extends Animal {
String tail;
public Cat(String brain, String heart, String tail) {
super(brain, heart);
this.tail = tail;
}
public static void main(String[] args) {
Cat cat = new Cat("Brain", "Heart", "Tail");
}
}
ใน Constructor Cat
เราเรียก Constructor Animal
และส่งผ่านสองฟิลด์ไปให้มัน เราจะต้องเริ่มต้นฟิลด์เดียวอย่างชัดเจนtail
ซึ่งAnimal
ไม่มีอยู่ จำได้ไหมที่เราบอกว่าเมื่อวัตถุถูกสร้างขึ้น Constructor ของคลาสพาเรนต์จะถูกเรียกก่อน? นี่คือเหตุผลว่าทำไมคำนี้super()
จึงควรมาก่อนในตัวสร้างเสมอ! มิฉะนั้น ตรรกะของคอนสตรัคเตอร์จะเสียหายและโปรแกรมจะสร้างข้อผิดพลาด
public class Cat extends Animal {
String tail;
public Cat(String brain, String heart, String tail) {
this.tail = tail;
super(brain, heart);//error!
}
public static void main(String[] args) {
Cat cat = new Cat("Brain", "Heart", "Tail");
}
}
คอมไพลเลอร์รู้ว่าเมื่อสร้างอ็อบเจ็กต์ของคลาสสืบทอด ตัวสร้างของคลาสฐานจะถูกเรียกก่อน และถ้าคุณพยายามเปลี่ยนพฤติกรรมนี้ด้วยตนเอง มันก็จะไม่อนุญาต
กระบวนการสร้างวัตถุ
ด้านบนนี้เราดูตัวอย่างที่มีคลาสพื้นฐานและคลาสพาเรนต์ -Animal
และCat
. ตอนนี้ เมื่อใช้ทั้งสองคลาสนี้เป็นตัวอย่าง เราจะดูกระบวนการสร้างอ็อบเจ็กต์และการเริ่มต้นตัวแปร เรารู้ว่าตัวแปรเป็นแบบคงที่และ ตัวแปรอินส แตนซ์ (ไม่คงที่) เรายังรู้ด้วยว่าคลาสพื้นฐานAnimal
มีตัวแปรของตัวเอง และคลาสลูกหลานก็Cat
มีตัวแปรของตัวเอง มาเพิ่ม ตัวแปรคงที่หนึ่งตัวให้กับคลาสเพื่อAnimal
ความชัดเจน Cat
ตัวแปรanimalCount
คลาสAnimal
จะเป็นจำนวนสายพันธุ์สัตว์ทั้งหมดบนโลก และตัวแปรcatsCount
จะเป็นจำนวนสายพันธุ์แมว นอกจากนี้ เราจะกำหนดค่าเริ่มต้นให้กับตัวแปรที่ไม่คงที่ทั้งหมดของทั้งสองคลาส (ซึ่งจะเปลี่ยนแปลงในตัวสร้าง)
public class Animal {
String brain = "The initial value of brain in the Animal class";
String heart = "The initial value of heart in the Animal class";
public static int animalCount = 7700000;
public Animal(String brain, String heart) {
System.out.println("The constructor of the Animal base class is being executed");
System.out.println("Have the variables of the Animal class already been initialized?");
System.out.println("The current value of the static variable animalCount = " + animalCount);
System.out.println("Current value of brain in class Animal = " + this.brain);
System.out.println("Current value of heart in class Animal = " + this.heart);
System.out.println("Have the variables of the Cat class already been initialized?");
System.out.println("The current value of the static variable catsCount = " + Cat.catsCount);
this.brain = brain;
this.heart = heart;
System.out.println("Animal base class constructor completed!");
System.out.println("Current value of brain = " + this.brain);
System.out.println("Current value of heart = " + this.heart);
}
}
public class Cat extends Animal {
String tail = "The initial value of tail in the Cat class";
static int catsCount = 37;
public Cat(String brain, String heart, String tail) {
super(brain, heart);
System.out.println("The constructor of the Cat class has started (the Animal constructor has already been executed)");
System.out.println("The current value of the static variable catsCount = " + catsCount);
System.out.println("Current value tail = " + this.tail);
this.tail = tail;
System.out.println("Current value tail = " + this.tail);
}
public static void main(String[] args) {
Cat cat = new Cat("Brain", "Heart", "Tail");
}
}
ดังนั้นเราจึงสร้างวัตถุใหม่ของคลาสCat
ที่สืบทอดมาจากAnimal
. มาเพิ่มเอาต์พุตคอนโซลโดยละเอียดให้กับโปรแกรมของเราเพื่อดูว่าจะเกิดอะไรขึ้นและเรียงลำดับอย่างไร นี่คือสิ่งที่จะส่งออกไปยังคอนโซลอันเป็นผลมาจากการสร้างวัตถุCat
:
Выполняется конструктор базового класса Animal
Были ли уже проинициализированы переменные класса Animal?
Текущее meaning статической переменной animalCount = 7700000
Текущее meaning brain в классе Animal = Изначальное meaning brain в классе Animal
Текущее meaning heart в классе Animal = Изначальное meaning heart в классе Animal
Были ли уже проинициализированы переменные класса Cat?
Текущее meaning статической переменной catsCount = 37
Конструктор базового класса Animal завершил работу!
Текущее meaning brain = Мозг
Текущее meaning heart = Сердце
Конструктор класса Cat начал работу (конструктор Animal уже был выполнен)
Текущее meaning статической переменной catsCount = 37
Текущее meaning tail = Изначальное meaning tail в классе Cat
Текущее meaning tail = Хвост
ตอนนี้เราสามารถเห็นได้อย่างชัดเจนว่าตัวแปรลำดับใดที่ถูกเตรียมใช้งานและตัวสร้างจะถูกเรียกเมื่อสร้างวัตถุใหม่:
-
ตัวแปรคง ที่ ของคลาสพื้นฐาน ( ) จะถูกเตรียมใช้
Animal
งาน ในกรณีของเรา ตัวแปรanimalCount
คลาสAnimal
ถูกกำหนดให้เป็นค่า 7700000 -
ตัวแปรคงที่ของคลาสลูกหลาน ( ) จะถูกเตรียมใช้
Cat
งาน โปรดทราบ - เรายังอยู่ใน ConstructorAnimal
และคอนโซลแจ้งว่า:Выполняется конструктор базового класса Animal Были ли уже проинициализированы переменные класса Animal? Текущее meaning статической переменной animalCount = 7700000 Текущее meaning brain в классе Animal = Изначальное meaning brain в классе Animal Текущее meaning heart в классе Animal = Изначальное meaning heart в классе Animal Были ли уже проинициализированы переменные класса Cat? Текущее meaning статической переменной catsCount = 37
-
ถัดไปตัวแปรที่ไม่คงที่ของคลาสฐาน จะถูกเตรียมใช้ งาน เราได้กำหนดค่าเริ่มต้นให้กับพวกเขาโดยเฉพาะ ซึ่งจะเปลี่ยนเป็นค่าใหม่ใน Constructor ตัวสร้าง
Animal
ยังทำงานไม่เสร็จ แต่brain
มีheart
การกำหนดค่าเริ่มต้นแล้ว:Выполняется конструктор базового класса Animal Были ли уже проинициализированы переменные класса Animal? Текущее meaning статической переменной animalCount = 7700000 Текущее meaning brain в классе Animal = Изначальное meaning brain в классе Animal Текущее meaning heart в классе Animal = Изначальное meaning heart в классе Animal
-
ตัวสร้างคลาสพื้นฐานเริ่มทำงาน
เราได้เห็นแล้วว่าขั้นตอนนี้เป็นเพียงขั้นตอนที่สี่: ในสามจุดแรก ในขณะที่ตัวสร้างเริ่มทำงาน
Animal
ตัวแปรจำนวนมากได้ถูกกำหนดค่าไว้แล้ว -
การเริ่มต้นเขตข้อมูลที่ไม่คงที่ของคลาสลูก (
Cat
)มันเกิดขึ้นก่อนที่นักออกแบบ
Cat
จะเริ่มทำงานในขณะที่เขาเริ่มทำงาน ตัวแปร
tail
มีค่าอยู่แล้ว:Конструктор класса Cat начал работу (конструктор Animal уже был выполнен) Текущее meaning статической переменной catsCount = 37 Текущее meaning tail = Изначальное meaning tail в классе Cat
-
ตัวสร้างของคลาสลูกหลานเรียกว่า
Cat
GO TO FULL VERSION