JavaRush /Blog Java /Random-FR /Constructeurs de classe de base

Constructeurs de classe de base

Publié dans le groupe Random-FR
Bonjour! La dernière fois, nous avons parlé des constructeurs et nous avons beaucoup appris sur eux. Nous allons maintenant parler des constructeurs de classes de base. Qu'est-ce qu'une classe de base ? Le fait est qu’en Java, plusieurs classes différentes peuvent avoir une origine commune. Constructeurs de classe de base - 2C'est ce qu'on appelle l'héritage . Plusieurs classes descendantes peuvent avoir une classe ancêtre commune. Par exemple, imaginez que nous ayons une classe Animal(animal) :
public class Animal {

   String name;
   int age;
}
On peut créer pour cela, par exemple, 2 classes descendantes - Catet Dog. Cela se fait à l'aide du mot-clé extends.
public class Cat extends Animal {

}

public class Dog extends Animal {

}
Cela pourrait nous être utile à l'avenir. Par exemple, si la tâche consiste à attraper des souris, nous créerons un objet dans le programme Cat. Si la tâche consiste à courir après un bâton, alors nous utilisons l'objet Dog. Et si nous créons un programme qui simule une clinique vétérinaire, il fonctionnera avec la classe Animal(pour pouvoir soigner aussi bien les chats que les chiens). Il est très important de se rappeler pour l'avenir que lors de la création d'un objet, le constructeur de sa classe de base est appelé en premier , et ensuite seulement le constructeur de la classe elle-même, dont nous créons l'objet, est appelé. Autrement dit, lors de la création d'un objet, Catle constructeur de classe fonctionnera en premier Animal, et ensuite seulement le constructeur Cat. Pour nous en assurer, ajoutons aux constructeurs Catet Animalsortons sur la console.
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();
   }
}
Sortie de la console :

Отработал конструктор Animal
Отработал конструктор Cat!
En effet, c’est ainsi que tout fonctionne ! Pourquoi est-ce? Par exemple, pour éviter de dupliquer les champs communs de deux classes. Par exemple, chaque animal a un cœur et un cerveau, mais tous les animaux n’ont pas de queue. Nous pouvons déclarer des champs communs à tous les animaux brainde heartla classe parent Animal, ainsi qu'un champ taildans la sous-classe Cat. Nous allons maintenant créer un constructeur pour la classe Cat, où nous transmettrons les 3 champs.
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");
   }
}
Faites attention:le constructeur fonctionne avec succès, bien que la classe Catn'ait pas de champs brainet heart. Ces champs ont été « extraits » de la classe de base Animal. La classe descendante a accès aux champs de la classe de base, Catils sont donc visibles dans notre classe. Par conséquent, nous n'avons pas besoin Catde dupliquer ces champs dans la classe - nous pouvons les extraire de la classe Animal. De plus, on peut appeler explicitement le constructeur de la classe de base dans le constructeur de la classe descendante. La classe de base est également appelée « superclasse », c'est pourquoi Java utilise le mot-clé super. Dans l'exemple précédent
public Cat(String brain, String heart, String tail) {
       this.brain = brain;
       this.heart = heart;
       this.tail = tail;
   }
Nous avons attribué séparément chaque champ de notre classe parent. En fait, vous n’êtes pas obligé de faire cela. Il suffit d'appeler le constructeur de la classe parent et de lui passer les paramètres nécessaires :
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");
   }
}
Dans le constructeur, Catnous avons appelé le constructeur Animalet lui avons transmis deux champs. Nous n'avons qu'à initialiser explicitement un champ - tailqui Animaln'est pas présent. Rappelez-vous comment nous avons dit que lorsqu'un objet est créé, le constructeur de la classe parent est appelé en premier ? C’est pourquoi le mot super()doit toujours venir en premier dans le constructeur ! Sinon, la logique des constructeurs sera brisée et le programme générera une erreur.
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");
   }
}
Le compilateur sait que lors de la création d'un objet d'une classe descendante, le constructeur de la classe de base est appelé en premier. Et si vous essayez de modifier manuellement ce comportement, cela ne le permettra pas.

Le processus de création d'un objet.

Ci-dessus, nous avons examiné un exemple avec une classe de base et une classe parent - Animalet Cat. Maintenant, en utilisant ces deux classes comme exemple, nous allons examiner le processus de création d'un objet et d'initialisation des variables. Nous savons que les variables sont statiques et les variables d'instance (non statiques). Nous savons également que la classe de base Animala ses propres variables et que la classe descendante Cata les siennes. Ajoutons une variable statique à la classe pour Animalplus de clarté . CatLa variable animalCountde classe Animalserait le nombre total d’espèces animales sur terre, et la variable catsCountserait le nombre d’espèces de chats. De plus, nous attribuerons des valeurs de départ à toutes les variables non statiques des deux classes (qui changeront ensuite dans le constructeur).
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");
   }
}
Nous créons donc un nouvel objet de la classe Cathéritée de Animal. Ajoutons une sortie console détaillée à notre programme pour voir ce qui va se passer et dans quel ordre. Voici ce qui sera affiché sur la console suite à la création d'un objetCat :

Выполняется конструктор базового класса 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 = Хвост
Ainsi, nous pouvons maintenant voir clairement dans quel ordre les variables sont initialisées et les constructeurs sont appelés lors de la création d'un nouvel objet :
  1. Les variables statiques de la classe de base ( ) sont initialisées Animal. Dans notre cas, la variable animalCountde classe Animalreçoit la valeur 7700000.

  2. Les variables statiques de la classe descendante ( ) sont initialisées Cat. Faites attention, nous sommes toujours à l'intérieur du constructeur Animalet la console dit déjà :

    
        Выполняется конструктор базового класса Animal
        Были ли уже проинициализированы переменные класса Animal?
        Текущее meaning статической переменной animalCount = 7700000
        Текущее meaning brain в классе Animal = Изначальное meaning brain в классе Animal
        Текущее meaning heart в классе Animal = Изначальное meaning heart в классе Animal
        Были ли уже проинициализированы переменные класса Cat?
        Текущее meaning статической переменной catsCount = 37
  3. Ensuite, les variables non statiques de la classe de base sont initialisées . Nous leur avons spécifiquement attribué des valeurs initiales, qui sont ensuite remplacées par de nouvelles dans le constructeur. Le constructeur Animaln'a pas encore terminé ses travaux, mais les valeurs initiales brainont heartdéjà été attribuées :

    
        Выполняется конструктор базового класса Animal
        Были ли уже проинициализированы переменные класса Animal?
        Текущее meaning статической переменной animalCount = 7700000
        Текущее meaning brain в классе Animal = Изначальное meaning brain в классе Animal
        Текущее meaning heart в классе Animal = Изначальное meaning heart в классе Animal
  4. Le constructeur de la classe de base commence à fonctionner .

    Nous avons déjà vu que cette étape n'est que la quatrième : dans les trois premiers points, au moment où le constructeur commence à travailler, Animalde nombreuses variables ont déjà reçu des valeurs.

  5. Initialisation des champs non statiques d'une classe enfant ( Cat).

    Cela se produit avant que le concepteur Catne commence à travailler.

    Au moment où il a commencé à travailler, la variable tailavait déjà une valeur :

    
    Конструктор класса Cat начал работу (конструктор Animal уже был выполнен)
    Текущее meaning статической переменной catsCount = 37
    Текущее meaning tail = Изначальное meaning tail в классе Cat
  6. Le constructeur de la classe descendante est appelé Cat

Voici à quoi ressemble le processus de création d’un objet en Java ! Je dois dire que nous ne sommes pas de grands fans du bachotage, mais il vaut mieux mémoriser l'ordre d'initialisation des variables et d'appel des constructeurs et les mémoriser pour l'avenir . Cela augmentera considérablement votre compréhension de la progression du programme et de l'état de vos objets à un moment donné. De plus, les classes n'ont souvent pas de classes parents directes (superclasses/classes de base). Dans ce cas, les éléments associés à la classe de base ne seront pas exécutés.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION