Animal
(الحيوان):
public class Animal {
String name;
int age;
}
يمكننا أن ننشئ لها، على سبيل المثال، فئتين تنازليتين - 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
. الآن سوف نقوم بإنشاء منشئ للفئة Cat
، حيث سنمرر جميع الحقول الثلاثة.
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
. علاوة على ذلك، يمكننا بشكل واضح استدعاء منشئ الفئة الأساسية في منشئ الفئة السلالة. تُسمى الفئة الأساسية أيضًا " الطبقة الفائقة "، ولهذا السبب تستخدم Java الكلمة الأساسية super
. في المثال السابق
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");
}
}
في المنشئ، Cat
قمنا باستدعاء المنشئ Animal
وقمنا بتمرير حقلين إليه. علينا فقط تهيئة حقل واحد بشكل صريح - tail
وهو Animal
غير موجود. تذكر كيف قلنا أنه عند إنشاء كائن، يتم استدعاء منشئ الفئة الأصل أولا؟ ولهذا السبب 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
. انتبه - مازلنا داخل المُنشئAnimal
، ووحدة التحكم تقول بالفعل:Выполняется конструктор базового класса Animal Были ли уже проинициализированы переменные класса Animal? Текущее meaning статической переменной animalCount = 7700000 Текущее meaning brain в классе Animal = Изначальное meaning brain в классе Animal Текущее meaning heart в классе Animal = Изначальное meaning heart в классе Animal Были ли уже проинициализированы переменные класса Cat? Текущее meaning статической переменной catsCount = 37
-
بعد ذلك، تتم تهيئة المتغيرات غير الثابتة للفئة الأساسية . لقد قمنا بتعيين قيم أولية لهم على وجه التحديد، والتي يتم تغييرها بعد ذلك إلى قيم جديدة في المُنشئ. لم يكمل المنشئ
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