CodeGym /Java blog /Tilfældig /Basisklasse konstruktører
John Squirrels
Niveau
San Francisco

Basisklasse konstruktører

Udgivet i gruppen
Hej! Sidste gang talte vi om konstruktører og lærte meget om dem. Nu skal vi tale om basisklasse-konstruktører .
Basisklasse konstruktører - 1
Hvad er en basisklasse ? Det hænger sammen med, at i Java kan flere forskellige klasser have en fælles oprindelse.
Basisklasse konstruktører - 2
Dette kaldes arv . Flere børneklasser kan have én fælles forfader. Forestil dig for eksempel, at vi har en Animalklasse:

public class Animal {
  
   String name;
   int age;
}
Vi kan erklære 2 børneklasser: Catog Dog. Dette gøres ved at bruge nøgleordet extends .

public class Cat extends Animal {

}

public class Dog extends Animal {
  
}
Vi kan finde dette nyttigt i fremtiden. For eksempel, hvis der er en opgave at fange mus, opretter vi et Cat objekt i vores program. Hvis opgaven er at jagte en pind, så bruger vi en Dog genstand. Og hvis vi laver et program, der simulerer en dyrlægeklinik, vil det fungere sammen med Animal klassen (og dermed kunne behandle både katte og hunde). Det er meget vigtigt at huske, at når et objekt oprettes, kaldes konstruktøren af ​​dets basisklasse først . Først efter at denne konstruktør er færdig, udfører programmet konstruktøren af ​​den klasse, der svarer til det objekt, vi opretter. Med andre ord, når du opretter et Catobjekt, køres konstruktøren først ,Animal og først bagefter køresCatkonstruktør udført . For at se dette skal du tilføje noget konsoloutput til Catog Animalkonstruktørerne.

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();
   }
}
Konsoludgang: Dyrekonstruktør udført Kattekonstruktør udført! Det virker faktisk sådan! Hvorfor? En grund er at undgå at duplikere felter, der deles mellem de to klasser. For eksempel har hvert dyr et hjerte og en hjerne, men ikke alle dyr har en hale. Vi kunne erklære hjerne- og hjertefelter , som er fælles for alle dyr, i forældreklassen Animalog et halefelt i Catunderklassen. . Nu vil vi erklære en Catklassekonstruktør, der tager argumenter for alle 3 felter.

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");
   }
}
Bemærk: Konstruktøren fungerer korrekt, selvom klassen Catikke har nogen hjerne- og hjertefelter . Disse felter er "arvet" fra Animalbasisklassen. Den nedarvede klasse har adgang til felterne i basisklassen , så de er synlige i vores Catklasse. Som et resultat behøver vi ikke at duplikere disse felter i Catklassen. Vi kan tage dem fra Animalklassen. Hvad mere er, kan vi eksplicit kalde basisklassekonstruktøren i børneklassekonstruktøren. En basisklasse kaldes også en " superklasse ". Det er derfor, Java bruger søgeordet super til at angive basisklassen. I det foregående eksempel

public Cat(String brain, String heart, String tail) {
       this.brain = brain;
       this.heart = heart;
       this.tail = tail;
   }
Vi tildelte hvert felt separat i vores forældreklasse. Vi behøver faktisk ikke gøre dette. Det er nok at kalde den overordnede klassekonstruktør og sende de nødvendige argumenter:

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");
   }
}
I Catkonstruktøren ringede vi til Animalkonstruktøren og passerede to felter. Vi havde kun ét felt at initialisere eksplicit: tail , som ikke er i Animal. Husker vi, at vi nævnte, at den overordnede klassekonstruktør kaldes først, når et objekt oprettes? Derfor skal super() altid være først i en konstruktør! Ellers vil konstruktørlogikken blive overtrådt, og programmet vil generere en fejl.

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");
   }
}
Compileren ved, at når et objekt i en underklasse oprettes, kaldes basisklassekonstruktøren først. Og hvis du prøver at ændre denne adfærd manuelt, vil compileren ikke tillade det.

Hvordan et objekt skabes

Vi har tidligere set på et eksempel med en basis- og forældreklasse: Animalog Cat. Ved at bruge disse to klasser som eksempler, vil vi nu se på processen med at skabe et objekt og initialisere variabler. Vi ved, at der er statiske og instans (ikke-statiske) variabler . Vi ved også, at Animalbasisklassen har variable, og Catbarneklassen har sine egne. For klarhedens skyld tilføjer vi én statisk variabel hver til klasserne Animalog Cat. AnimalCount - variablen i Animalklassen vil repræsentere det samlede antal dyrearter på Jorden og catCountvariabel vil angive antallet af kattearter. Derudover vil vi tildele startværdier til alle ikke-statiske variable i begge klasser (som så vil blive ændret i konstruktøren).

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");
   }
}
Så vi opretter en ny forekomst af Catklassen, som arver Animal. Vi har tilføjet nogle detaljerede konsoloutput for at se, hvad der sker, og i hvilken rækkefølge. Dette er, hvad der vil blive vist, når et Catobjekt oprettes: Animal base class constructor kører Er variablerne i Animal klassen allerede blevet initialiseret? Aktuel værdi af statisk variabel animalCount = 7700000 Aktuel værdi af hjerne i dyreklassen = Startværdi af hjerne i dyreklassen Nuværende værdi af hjerte i dyreklassen = Startværdi af hjerte i dyreklassen Har variablerne for Cat-klassen allerede blevet initialiseret? Aktuel værdi af statisk variabel catCount = 37 Dyrebaseklassekonstruktør er færdig! Aktuel værdi af hjerne = Hjerne Aktuel værdi hjerte = Hjerte Katteklassekonstruktøren er startet (Dyrekonstruktøren er allerede færdig) Aktuel værdi af statisk variabel catCount = 37 Aktuel værdi af hale = Startværdi af hale i Cat-klassen Aktuel værdi af hale = Hale Så nu kan vi tydeligt se rækkefølgen af ​​variabel initialisering og konstruktørkald, når et nyt objekt oprettes:
  1. Statiske variable for basisklassen ( Animal) initialiseres. I vores tilfælde er Animalklassens variable animalCount sat til 7700000.

  2. Statiske variabler for den underordnede klasse ( Cat) initialiseres.

    Bemærk: vi er stadig inde i konstruktøren Animal, og vi har allerede vist:

    Animal base class constructor kører
    Er variablerne i Animal klassen allerede blevet initialiseret?
    Aktuel værdi af statisk variabel animalCount = 7700000
    Aktuel værdi af hjerne i dyreklassen = Startværdi af hjerne i dyreklassen
    Nuværende værdi af hjerte i dyreklassen = Startværdi af hjerte i dyreklassen
    Har variablerne fra Cat-klassen allerede blevet initialiseret?
    Aktuel værdi af statisk variabel catCount = 37


  3. Derefter initialiseres de ikke-statiske variable i basisklassen . Vi har specifikt tildelt dem startværdier, som derefter erstattes i konstruktøren. Dyrekonstruktøren er ikke færdig endnu, men startværdierne for hjerne og hjerte er allerede blevet tildelt:

    Animal base class constructor kører
    Er variablerne i Animal klassen allerede blevet initialiseret?
    Aktuel værdi af statisk variabel animalCount = 7700000
    Aktuel værdi af hjerne i dyreklassen = Startværdi af hjerne i dyreklassen
    Nuværende værdi af hjerte i dyreklassen = Startværdi af hjerte i dyreklassen


  4. Basisklassekonstruktøren starter.
    Vi har allerede overbevist os selv om, at dette trin er fjerde: i de første tre trin i begyndelsen af ​​konstruktøren Animaler mange variable allerede blevet tildelt værdier.


  5. Ikke-statiske felter i den underordnede klasse ( Cat) initialiseres.
    Dette sker før Catkonstruktøren begynder at køre.
    Når den begynder at køre, har halevariablen allerede en værdi:

    Katteklassekonstruktøren er startet (Dyrekonstruktøren er allerede færdig) Aktuel værdi af statisk variabel catCount = 37 Aktuel værdi af hale = Startværdi af hale i Cat-klassen


  6. Konstruktøren af Cat​​børneklassen kaldes

    Og sådan ser det ud at skabe et objekt i Java!

    Jeg må sige, at vi ikke er store fans af udenadslære, men det er bedst at huske rækkefølgen af ​​variabel initialisering og konstruktørkald .

    Dette vil i høj grad øge din forståelse af programmets flow og tilstanden af ​​dine objekter på ethvert bestemt tidspunkt.

    Desuden bruger mange klasser ikke arv. I dette tilfælde gælder trinene relateret til basisklassen ikke.

Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION