JavaRush /Java-Blog /Random-DE /Konstruktoren der Basisklasse

Konstruktoren der Basisklasse

Veröffentlicht in der Gruppe Random-DE
Hallo! Letztes Mal haben wir über Konstrukteure gesprochen und viel über sie gelernt. Jetzt werden wir über so etwas wie Basisklassenkonstruktoren sprechen. Was ist eine Basisklasse ? Tatsache ist, dass in Java mehrere verschiedene Klassen einen gemeinsamen Ursprung haben können. Basisklassenkonstruktoren – 2Dies nennt man Vererbung . Mehrere Nachkommenklassen können eine gemeinsame Vorfahrenklasse haben. Stellen Sie sich zum Beispiel vor, wir hätten eine Klasse Animal(Tier):
public class Animal {

   String name;
   int age;
}
Wir können dafür zum Beispiel 2 Nachkommenklassen erstellen – Catund Dog. Dies geschieht mit dem Schlüsselwort extends.
public class Cat extends Animal {

}

public class Dog extends Animal {

}
Dies könnte für uns in Zukunft nützlich sein. Wenn die Aufgabe beispielsweise darin besteht, Mäuse zu fangen, erstellen wir im Programm ein Objekt Cat. Wenn die Aufgabe darin besteht, einem Stick nachzulaufen, dann verwenden wir das Objekt Dog. Und wenn wir ein Programm erstellen, das eine Tierklinik simuliert, funktioniert es mit der Klasse Animal(um sowohl Katzen als auch Hunde behandeln zu können). Es ist sehr wichtig, sich für die Zukunft daran zu erinnern, dass beim Erstellen eines Objekts zuerst der Konstruktor seiner Basisklasse und erst dann der Konstruktor der Klasse selbst aufgerufen wird, deren Objekt wir erstellen. Das heißt, beim Erstellen eines Objekts Catarbeitet zuerst der Klassenkonstruktor Animalund erst dann der Konstruktor Cat. Um dies sicherzustellen, ergänzen wir die Konstruktoren Catund Animalgeben sie auf der Konsole aus.
public class Animal {

   public Animal() {
       System.out.println(„Tierkonstrukteur abgeschlossen“);
   }
}


public class Cat extends Animal {

   public Cat() {
       System.out.println(„Der Konstrukteur Cat hat funktioniert!“);
   }

   public static void main(String[] args) {
       Cat cat = new Cat();
   }
}
Konsolenausgabe:

Отработал конструктор Animal
Отработал конструктор Cat!
Tatsächlich funktioniert das Ganze so! Wofür ist das? Um beispielsweise die Duplizierung gemeinsamer Felder zweier Klassen zu vermeiden. Beispielsweise hat jedes Tier ein Herz und ein Gehirn, aber nicht jedes Tier hat einen Schwanz. Wir können Felder, die allen Tieren gemeinsam sind, brainin heartder übergeordneten Klasse Animalund ein Feld tailin der Unterklasse deklarieren Cat. Jetzt erstellen wir einen Konstruktor für die Klasse Cat, in dem wir alle drei Felder übergeben.
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("Gehirn", "Herz", "Schwanz");
   }
}
Passt auf:Der Konstruktor funktioniert erfolgreich, obwohl die Klasse Catkeine Felder brainund hat heart. Diese Felder wurden aus der Basisklasse „heraufgezogen“ Animal. Die Nachkommenklasse hat Zugriff auf die Felder der Basisklasse, sodass Catdiese in unserer Klasse sichtbar sind. Daher müssen wir diese Felder nicht Catin der Klasse duplizieren – wir können sie aus der Klasse übernehmen Animal. Darüber hinaus können wir den Konstruktor der Basisklasse explizit im Konstruktor der Nachkommenklasse aufrufen. Die Basisklasse wird auch „ Superklasse “ genannt, weshalb Java das Schlüsselwort verwendet super. Im vorherigen Beispiel
public Cat(String brain, String heart, String tail) {
       this.brain = brain;
       this.heart = heart;
       this.tail = tail;
   }
Wir haben jedes Feld, das sich in unserer übergeordneten Klasse befindet, separat zugewiesen. Tatsächlich müssen Sie dies nicht tun. Es genügt, den Konstruktor der übergeordneten Klasse aufzurufen und ihm die notwendigen Parameter zu übergeben:
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("Gehirn", "Herz", "Schwanz");
   }
}
Im Konstruktor Cathaben wir den Konstruktor aufgerufen Animalund ihm zwei Felder übergeben. Wir müssen nur ein Feld explizit initialisieren – taildas Animalnicht vorhanden ist. Erinnern Sie sich, wie wir gesagt haben, dass beim Erstellen eines Objekts zuerst der Konstruktor der übergeordneten Klasse aufgerufen wird? Deshalb super()sollte das Wort im Konstruktor immer an erster Stelle stehen! Andernfalls wird die Logik der Konstruktoren beschädigt und das Programm generiert einen Fehler.
public class Cat extends Animal {

   String tail;

   public Cat(String brain, String heart, String tail) {
       this.tail = tail;
       super(brain, heart);//Fehler!
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Gehirn", "Herz", "Schwanz");
   }
}
Der Compiler weiß, dass beim Erstellen eines Objekts einer Nachfolgeklasse zuerst der Konstruktor der Basisklasse aufgerufen wird. Und wenn Sie versuchen, dieses Verhalten manuell zu ändern, wird dies nicht zugelassen.

Der Prozess der Erstellung eines Objekts.

Oben haben wir uns ein Beispiel mit einer Basis- und einer übergeordneten Klasse angesehen – Animalund Cat. Am Beispiel dieser beiden Klassen betrachten wir nun den Prozess der Objekterstellung und Initialisierung von Variablen. Wir wissen, dass Variablen statische und Instanzvariablen (nicht statisch) sind. Wir wissen auch, dass die Basisklasse Animalihre eigenen Variablen hat und die Nachkommenklasse Catihre eigenen. Fügen wir der Klasse aus Gründen der AnimalÜbersichtlichkeit eine statische Variable hinzu . CatDie Klassenvariable wäre die Gesamtzahl der Tierarten auf der Erde und die Variable animalCountwäre die Zahl der Katzenarten. Darüber hinaus werden wir allen nicht statischen Variablen beider Klassen Startwerte zuweisen (die sich dann im Konstruktor ändern). AnimalcatsCount
public class Animal {

   String brain = „Der anfängliche Wert des Gehirns in der Tierklasse“;
   String heart = „Der Anfangswert des Herzens in der Tierklasse“;

   public static int animalCount = 7700000;

   public Animal(String brain, String heart) {
       System.out.println(„Der Konstruktor der Animal-Basisklasse wird ausgeführt“);
       System.out.println(„Wurden die Variablen der Animal-Klasse bereits initialisiert?“);
       System.out.println(„Der aktuelle Wert der statischen Variablen animalCount =“ + animalCount);
       System.out.println(„Aktueller Wert des Gehirns in der Klasse Tier =“ + this.brain);
       System.out.println(„Aktueller Wert des Herzens in der Klasse Tier =“ + this.heart);
       System.out.println(„Sind die Variablen der Cat-Klasse bereits initialisiert?“);
       System.out.println(„Der aktuelle Wert der statischen Variablen catsCount =“ + Cat.catsCount);

       this.brain = brain;
       this.heart = heart;
       System.out.println(„Animal-Basisklassenkonstruktor abgeschlossen!“);
       System.out.println(„Aktueller Wert des Gehirns =“ + this.brain);
       System.out.println(„Aktueller Wert des Herzens =“ + this.heart);
   }
}

public class Cat extends Animal {

   String tail = „Der Anfangswert von tail in der Cat-Klasse“;

   static int catsCount = 37;

   public Cat(String brain, String heart, String tail) {
       super(brain, heart);
       System.out.println(„Der Konstruktor der Cat-Klasse wurde gestartet (der Animal-Konstruktor wurde bereits ausgeführt)“);
       System.out.println(„Der aktuelle Wert der statischen Variablen catsCount =“ + catsCount);
       System.out.println(„Aktueller Wert tail =“ + this.tail);
       this.tail = tail;
       System.out.println(„Aktueller Wert tail =“ + this.tail);
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Gehirn", "Herz", "Schwanz");
   }
}
Also erstellen wir ein neues Objekt der Catvon geerbten Klasse Animal. Fügen wir unserem Programm eine detaillierte Konsolenausgabe hinzu, um zu sehen, was passieren wird und in welcher Reihenfolge. Folgendes wird als Ergebnis der Objekterstellung an die Konsole ausgegeben Cat:

Выполняется конструктор базового класса Animal
Были ли уже проинициализированы переменные класса Animal?
Текущее Bedeutung статической переменной animalCount = 7700000
Текущее Bedeutung brain в классе Animal = Изначальное Bedeutung brain в классе Animal
Текущее Bedeutung heart в классе Animal = Изначальное Bedeutung heart в классе Animal
Были ли уже проинициализированы переменные класса Cat?
Текущее Bedeutung статической переменной catsCount = 37
Конструктор базового класса Animal завершил работу!
Текущее Bedeutung brain = Мозг
Текущее Bedeutung heart = Сердце
Конструктор класса Cat начал работу (конструктор Animal уже был выполнен)
Текущее Bedeutung статической переменной catsCount = 37
Текущее Bedeutung tail = Изначальное Bedeutung tail в классе Cat
Текущее Bedeutung tail = Хвост
Jetzt können wir deutlich erkennen, in welcher Reihenfolge Variablen initialisiert und Konstruktoren aufgerufen werden, wenn ein neues Objekt erstellt wird:
  1. Statische Variablen der Basisklasse ( ) werden initialisiert Animal. In unserem Fall wird der animalCountKlassenvariablen Animalder Wert 7700000 zugewiesen.

  2. Die statischen Variablen der Nachkommenklasse ( ) werden initialisiert Cat. Achtung – wir befinden uns noch im Konstruktor Animalund die Konsole sagt bereits:

    
        Выполняется конструктор базового класса Animal
        Были ли уже проинициализированы переменные класса Animal?
        Текущее Bedeutung статической переменной animalCount = 7700000
        Текущее Bedeutung brain в классе Animal = Изначальное Bedeutung brain в классе Animal
        Текущее Bedeutung heart в классе Animal = Изначальное Bedeutung heart в классе Animal
        Были ли уже проинициализированы переменные класса Cat?
        Текущее Bedeutung статической переменной catsCount = 37
  3. Als nächstes werden nicht statische Variablen der Basisklasse initialisiert . Wir haben ihnen gezielt Anfangswerte zugewiesen, die dann im Konstruktor in neue geändert werden. Der Konstruktor Animalhat seine Arbeit noch nicht abgeschlossen, aber die Anfangswerte brainwurden heartbereits zugewiesen:

    
        Выполняется конструктор базового класса Animal
        Были ли уже проинициализированы переменные класса Animal?
        Текущее Bedeutung статической переменной animalCount = 7700000
        Текущее Bedeutung brain в классе Animal = Изначальное Bedeutung brain в классе Animal
        Текущее Bedeutung heart в классе Animal = Изначальное Bedeutung heart в классе Animal
  4. Der Basisklassenkonstruktor beginnt zu arbeiten .

    Wir haben bereits gesehen, dass dieser Schritt erst der vierte ist: In den ersten drei Punkten sind zu dem Zeitpunkt, an dem der Konstruktor seine Arbeit aufnimmt, Animalvielen Variablen bereits Werte zugewiesen.

  5. Initialisieren nicht statischer Felder einer untergeordneten Klasse ( Cat).

    Dies geschieht, bevor der Designer Catmit der Arbeit beginnt.

    Als er mit der Arbeit begann, tailhatte die Variable bereits einen Wert:

    
    Конструктор класса Cat начал работу (конструктор Animal уже был выполнен)
    Текущее Bedeutung статической переменной catsCount = 37
    Текущее Bedeutung tail = Изначальное Bedeutung tail в классе Cat
  6. Der Konstruktor der Nachkommenklasse wird aufgerufen Cat

So sieht der Prozess der Objekterstellung in Java aus! Ich muss sagen, dass wir keine großen Fans des Paukens sind, aber es ist besser, sich die Reihenfolge der Initialisierung von Variablen und des Aufrufs von Konstruktoren zu merken und sie für die Zukunft im Gedächtnis zu behalten . Dies wird Ihr Verständnis für den Fortschritt des Programms und den Status Ihrer Objekte zu jedem Zeitpunkt erheblich verbessern. Darüber hinaus haben Klassen oft keine direkten übergeordneten Klassen (Superklassen/Basisklassen). In diesem Fall werden die mit der Basisklasse verknüpften Elemente nicht ausgeführt.
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION