CodeGym/Java блог/Случаен/Конструктори на базов клас
John Squirrels
Ниво
San Francisco

Конструктори на базов клас

Публикувано в групата
здрасти Миналия път говорихме за конструктори и научихме много за тях. Сега ще говорим за конструктори на базов клас .
Конструктори на базов клас - 1
Какво е базов клас ? Това е свързано с факта, че в Java няколко различни класа могат да имат общ произход.
Конструктори на базов клас - 2
Това се нарича наследяване . Няколко дъщерни класа могат да имат един общ предшественик. Например, представете си, че имаме 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 класа (и по този начин ще може да лекува Howто котки, така и кучета). Много е важно да запомните, че когато се създава обект, първо се извиква конструкторът на неговия базов клас . Едва след като този конструктор е завършен, програмата изпълнява конструктора на класа, съответстващ на обекта, който създаваме. С други думи, когато се създава Catобект, първо се изпълнява конструкторът иAnimal едва след товаCatизпълнен конструктор . За да видите това, добавете малко конзолен изход към Catи Animalконструкторите.
public class Animal {

   public Animal() {
       System.out.println("Animal constructor executed");
   }
}


public class Cat extends Animal {

   public Cat() {
       System.out.println("Cat constructor executed!");
   }

   public static void main(String[] args) {
       Cat cat = new Cat();
   }
}
Изход от конзолата: Конструкторът на животни е изпълнен Конструкторът на котка е изпълнен! Наистина, работи по този начин! Защо? Една от причините е да се избегне дублиране на полета, споделени между двата класа. Например всяко животно има сърце и мозък, но не всяко животно има опашка. Можем да декларираме мозъчни и сърдечни полета, които са общи за всички животни, в Animalродителския клас и поле на опашката в Catподкласа. . Сега ще декларираме 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няма мозъчни и сърдечни полета . Тези полета са "наследени" от 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конструктора и предадохме две полета. Имахме само едно поле за изрично инициализиране: опашка , което не е в 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 в класа ще представлява общия брой животински видове на Земята, а catCountAnimalпроменлива ще означава броя на видовете котки. Освен това ще присвоим начални стойности на всички нестатични променливи в двата класа (които след това ще бъдат променени в конструктора).
public class Animal {

   String brain = "Initial value of brain in the Animal class";
   String heart = "Initial value of heart in the Animal class";

   public static int animalCount = 7700000;

   public Animal(String brain, String heart) {
       System.out.println("Animal base class constructor is running");
       System.out.println("Have the variables of the Animal class already been initialized?");
       System.out.println("Current value of static variable animalCount = " + animalCount);
       System.out.println("Current value of brain in the Animal class = " + this.brain);
       System.out.println("Current value of heart in the Animal class = " + this.heart);
       System.out.println("Have the variables of the Cat class already been initialized?");
       System.out.println("Current value of static variable catCount = " + Cat.catCount);

       this.brain = brain;
       this.heart = heart;
       System.out.println("Animal base class constructor is done!");
       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 = "Initial value of tail in the Cat class";

   static int catCount = 37;

   public Cat(String brain, String heart, String tail) {
       super(brain, heart);
       System.out.println("The cat class constructor has started (The Animal constructor already finished)");
       System.out.println("Current value of static variable catCount = " + catCount);
       System.out.println("Current value of tail = " + this.tail);
       this.tail = tail;
       System.out.println("Current value of tail = " + this.tail);
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
Така че създаваме нов екземпляр на Catкласа, който наследява Animal. Добавихме подробен конзолен изход, за да видим Howво се случва и в Howъв ред. Ето Howво ще се покаже, когато Catбъде създаден обект: Конструкторът на базовия клас Animal работи. Инициализирани ли са вече променливите на класа Animal? Текуща стойност на статичната променлива animalCount = 7700000 Текуща стойност на мозъка в класа Animal = Първоначалната стойност на мозъка в класа Animal Текущата стойност на сърцето в класа Animal = Първоначалната стойност на сърцето в класа Animal Вече имате променливите на класа Cat инициализирано? Текуща стойност на статичната променлива catCount = 37 Конструкторът на базовия клас за животни е готов! Текуща стойност на мозъка = Мозък Текуща стойност heart = Heart Конструкторът на клас cat е стартиран (Конструкторът Animal вече е завършен) Текуща стойност на статичната променлива catCount = 37 Текуща стойност на опашката = Първоначална стойност на опашката в класа Cat Текуща стойност на опашката = Опашка И така, сега можем ясно да видим реда на инициализацията на променливите и извикванията на конструктора, когато се създава нов обект:
  1. Статичните променливи на базовия клас ( Animal) се инициализират. В нашия случай Animalпроменливата animalCount на класа е зададена на 7700000.

  2. Статичните променливи на дъщерния клас ( Cat) се инициализират.

    Забележка: все още сме вътре в Animalконструктора и вече сме показали:

    Конструкторът на базовия клас Animal работи.
    Инициализирани ли са вече променливите на класа Animal?
    Текуща стойност на статичната променлива animalCount = 7700000
    Текуща стойност на мозъка в класа Animal = Първоначалната стойност на мозъка в класа Animal
    Текущата стойност на сърцето в класа Animal = Първоначалната стойност на сърцето в класа Animal
    Вече имате променливите на класа Cat инициализирано?
    Текуща стойност на статичната променлива catCount = 37


  3. След това се инициализират нестатичните променливи на базовия клас . Специално им присвоихме начални стойности, които след това се заменят в конструктора. Конструкторът Animal все още не е завършен, но първоначалните стойности на мозъка и сърцето вече са зададени:

    Конструкторът на базовия клас Animal работи.
    Инициализирани ли са вече променливите на класа Animal?
    Текуща стойност на статичната променлива animalCount = 7700000
    Текуща стойност на мозъка в класа Animal = Първоначална стойност на мозъка в класа Animal
    Текуща стойност на сърцето в класа Animal = Първоначална стойност на сърцето в класа Animal


  4. Конструкторът на базов клас стартира.
    Вече се убедихме, че тази стъпка е четвърта: в първите три стъпки в началото на Animalконструктора на много променливи вече са присвоени стойности.


  5. Нестатичните полета на дъщерния клас ( Cat) се инициализират.
    Това се случва преди Catконструкторът да започне да работи.
    Когато започне да работи, променливата на опашката вече има стойност:

    Конструкторът на клас cat е стартиран (Конструкторът Animal вече е завършен) Текуща стойност на статичната променлива catCount = 37 Текуща стойност на опашката = Първоначална стойност на опашката в класа Cat


  6. CatИзвиква се конструкторът на дъщерния клас

    Ето How изглежда създаването на обект в Java!

    Трябва да кажа, че не сме големи фенове на ученето наизуст, но е най-добре да запомните реда на инициализацията на променливите и извикванията на конструктора .

    Това значително ще увеличи вашето разбиране за потока на програмата и състоянието на вашите обекти във всеки конкретен момент.

    Освен това много класове не използват наследяване. В този случай стъпките, свързани с базовия клас, не се прилагат.

Коментари
  • Популярен
  • Нов
  • Стар
Трябва да сте влезли, за да оставите коментар
Тази страница все още няма коментари