CodeGym/Java blogg/Slumpmässig/Basklasskonstruktörer
John Squirrels
Nivå
San Francisco

Basklasskonstruktörer

Publicerad i gruppen
Hej! Förra gången pratade vi om konstruktörer och lärde oss mycket om dem. Nu ska vi prata om basklasskonstruktörer .
Basklasskonstruktörer - 1
Vad är en basklass ? Det har att göra med att i Java kan flera olika klasser ha ett gemensamt ursprung.
Basklasskonstruktörer - 2
Detta kallas arv . Flera barnklasser kan ha en gemensam anfader. Föreställ dig till exempel att vi har en Animalklass:
public class Animal {

   String name;
   int age;
}
Vi kan deklarera 2 barnklasser: Catoch Dog. Detta görs med nyckelordet extends .
public class Cat extends Animal {

}

public class Dog extends Animal {

}
Vi kan ha nytta av detta i framtiden. Till exempel, om det finns en uppgift att fånga möss, skapar vi ett Cat objekt i vårt program. Om uppgiften är att jaga efter en pinne, så använder vi ett Dog föremål. Och om vi skapar ett program som simulerar en veterinärklinik kommer det att fungera med klassen ( Animal och därmed kunna behandla både katter och hundar). Det är mycket viktigt att komma ihåg att när ett objekt skapas, kallas konstruktorn för dess basklass först . Först efter att konstruktören är klar kör programmet konstruktorn för klassen som motsvarar objektet vi skapar. Med andra ord, när du skapar ett Catobjekt körs konstruktorn först ,Animal och först efteråt körsCatkonstruktör utförd . För att se detta, lägg till lite konsolutdata till Catoch Animalkonstruktörerna.
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();
   }
}
Konsolutdata: Djurkonstruktör körd Cat konstruktor körd! Visst, det fungerar så! Varför? Ett skäl är att undvika att duplicera fält som delas mellan de två klasserna. Till exempel har varje djur ett hjärta och en hjärna, men inte alla djur har en svans. Vi skulle kunna deklarera hjärn- och hjärtfält , som är gemensamma för alla djur, i Animalföräldraklassen, och ett svansfält i Catunderklassen. . Nu ska vi deklarera en Catklasskonstruktor som tar argument för alla tre fälten.
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");
   }
}
Notera: Konstruktorn fungerar korrekt även om klassen Catinte har några hjärn- och hjärtfält . Dessa fält "ärvs" från Animalbasklassen. Den ärvda klassen har tillgång till fälten i basklassen , så de är synliga i vår Catklass. Som ett resultat behöver vi inte duplicera dessa fält i klassen Cat. Vi kan ta dem från Animalklassen. Dessutom kan vi uttryckligen kalla basklasskonstruktorn i barnklasskonstruktorn. En basklass kallas också en " superklass ". Det är därför Java använder nyckelordet super för att indikera basklassen. I föregående exempel
public Cat(String brain, String heart, String tail) {
       this.brain = brain;
       this.heart = heart;
       this.tail = tail;
   }
Vi tilldelade varje fält separat i vår föräldraklass. Vi behöver faktiskt inte göra det här. Det räcker att anropa den överordnade klasskonstruktören och skicka de nödvändiga argumenten:
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 Catkonstruktorn ringde vi Animalkonstruktören och passerade två fält. Vi hade bara ett fält att explicit initiera: tail , som inte är i Animal. Kom ihåg att vi nämnde att den överordnade klasskonstruktorn anropas först när ett objekt skapas? Det är därför super() alltid ska vara först i en konstruktor! Annars kommer konstruktorlogiken att kränkas och programmet genererar ett fel.
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");
   }
}
Kompilatorn vet att när ett objekt i en barnklass skapas, anropas basklasskonstruktorn först. Och om du försöker ändra detta beteende manuellt, tillåter inte kompilatorn det.

Hur ett objekt skapas

Vi har tidigare tittat på ett exempel med en bas- och förälderklass: Animaloch Cat. Med dessa två klasser som exempel kommer vi nu att titta på processen att skapa ett objekt och initiera variabler. Vi vet att det finns statiska och instansvariabler (icke-statiska) . Vi vet också att Animalbasklassen har variabler och att Catbarnklassen har sina egna. För tydlighetens skull lägger vi till en statisk variabel var och en till klasserna Animaloch . CatAnimalCount - variabeln i Animalklassen kommer att representera det totala antalet djurarter på jorden och catCountvariabel kommer att beteckna antalet kattarter. Dessutom kommer vi att tilldela startvärden till alla icke-statiska variabler i båda klasserna (som sedan kommer att ändras i konstruktorn).
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 skapar en ny instans av Catklassen, som ärver Animal. Vi har lagt till lite detaljerad konsolutgång för att se vad som händer och i vilken ordning. Detta är vad som kommer att visas när ett Catobjekt skapas: Djurbasklasskonstruktorn körs Har variablerna för klassen Animal redan initierats? Aktuellt värde för statisk variabel animalCount = 7700000 Aktuellt värde för hjärnan i klassen Animal = Initialt värde på hjärnan i klassen Animal Aktuellt värde på hjärta i klassen Animal = Initialt värde på hjärta i klassen Animal Har variablerna för klassen Cat redan har initierats? Aktuellt värde för statisk variabel catCount = 37 Djurbasklasskonstruktör är klar! Aktuellt värde för hjärna = Hjärna Aktuellt värde hjärta = Hjärta Kattklasskonstruktören har startat (Djurkonstruktören är redan klar) Aktuellt värde för statisk variabel catCount = 37 Aktuellt värde för svans = Initialt värde för svans i Katt-klassen Aktuellt värde på svans = Svans Så nu kan vi tydligt se ordningen för variabelinitiering och konstruktoranrop när ett nytt objekt skapas:
  1. Statiska variabler för basklassen ( Animal) initieras. I vårt fall är Animalklassens variabel animalCount satt till 7700000.

  2. Statiska variabler för den underordnade klassen ( Cat) initieras.

    Obs: vi är fortfarande inne i Animalkonstruktören och vi har redan visat:

    Djurbasklasskonstruktorn körs
    Har variablerna för klassen Animal redan initierats?
    Aktuellt värde för statisk variabel animalCount = 7700000
    Aktuellt värde för hjärnan i klassen Animal = Initialt värde för hjärnan i klassen Animal
    Nuvarande värde på hjärta i klassen Animal = Initialt värde på hjärta i klassen
    Animal har initierats?
    Aktuellt värde för statisk variabel catCount = 37


  3. Sedan initieras de icke-statiska variablerna för basklassen . Vi tilldelade dem specifikt initiala värden, som sedan ersätts i konstruktorn. Djurkonstruktören har inte avslutats än, men de initiala värdena för hjärna och hjärta har redan tilldelats:

    Djurbasklasskonstruktorn körs
    Har variablerna för klassen Animal redan initierats?
    Aktuellt värde för statisk variabel animalCount = 7700000
    Aktuellt värde för hjärnan i klassen Animal =
    Initialt värde på hjärnan i klassen Djur.


  4. Basklasskonstruktorn startar.
    Vi har redan övertygat oss själva om att detta steg är fjärde: i de första tre stegen i början av konstruktorn Animalhar många variabler redan tilldelats värden.


  5. Icke-statiska fält för den underordnade klassen ( ) initieras Cat.
    Detta händer innan Catkonstruktorn börjar köra.
    När den börjar köras har svansvariabeln redan ett värde:

    Kattklasskonstruktören har startat (Djurkonstruktören är redan klar) Aktuellt värde för statisk variabel catCount = 37 Aktuellt värde på svans = Initialt värde för svans i klassen Cat


  6. Konstruktören av Catbarnklassen kallas

    Och så ser det ut att skapa ett objekt i Java!

    Jag måste säga att vi inte är stora fans av rote-learning, men det är bäst att memorera ordningen för variabelinitiering och konstruktoranrop .

    Detta kommer att avsevärt öka din förståelse för programmets flöde och tillståndet för dina objekt vid varje särskilt ögonblick.

    Dessutom använder många klasser inte arv. I det här fallet gäller inte stegen relaterade till basklassen.

Kommentarer
  • Populär
  • Ny
  • Gammal
Du måste vara inloggad för att lämna en kommentar
Den här sidan har inga kommentarer än