CodeGym /Blog Java /Random-FR /Constructeurs de classe de base
Auteur
Volodymyr Portianko
Java Engineer at Playtika

Constructeurs de classe de base

Publié dans le groupe Random-FR
Salut! La dernière fois, nous avons parlé des constructeurs et avons beaucoup appris à leur sujet. Nous allons maintenant parler des constructeurs de classe de base .
Constructeurs de classe de base - 1
Qu'est-ce qu'une classe de base ? Cela tient au fait qu'en Java plusieurs classes différentes peuvent avoir une origine commune.
Constructeurs de classe de base - 2
C'est ce qu'on appelle l'héritage . Plusieurs classes enfant peuvent avoir un ancêtre commun. Par exemple, imaginons que nous ayons une Animalclasse :

public class Animal {
  
   String name;
   int age;
}
On peut déclarer 2 classes enfants : Catet Dog. Ceci est fait en utilisant le mot clé extend .

public class Cat extends Animal {

}

public class Dog extends Animal {
  
}
Nous pourrions trouver cela utile à l'avenir. Par exemple, s'il existe une tâche pour attraper des souris, nous allons créer un Cat objet dans notre programme. Si la tâche consiste à courir après un bâton, nous utiliserons un Dog objet. Et si nous créons un programme qui simule une clinique vétérinaire, il fonctionnera avec la Animal classe (et pourra ainsi traiter aussi bien les chats que les chiens). Il est très important de se rappeler que lorsqu'un objet est créé, le constructeur de sa classe de base est d'abord appelé . Ce n'est qu'après que ce constructeur est terminé que le programme exécute le constructeur de la classe correspondant à l'objet que nous créons. En d'autres termes, lors de la création d'un Catobjet, le Animalconstructeur est exécuté en premier , et ce n'est qu'ensuite que leCatconstructeur exécuté . Pour voir cela, ajoutez une sortie de console aux constructeurs Catet 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();
   }
}
Sortie console : Constructeur animal exécuté Constructeur chat exécuté ! En effet, ça marche comme ça ! Pourquoi? L'une des raisons est d'éviter la duplication des champs partagés entre les deux classes. Par exemple, chaque animal a un cœur et un cerveau, mais tous les animaux n'ont pas de queue. Nous pourrions déclarer les champs cerveau et cœur , qui sont communs à tous les animaux, dans la Animalclasse mère, et un champ queue dans la Catsous-classe. . Nous allons maintenant déclarer un Catconstructeur de classe qui prend des arguments pour 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");
   }
}
Remarque : Le constructeur fonctionne correctement même si la Catclasse n'a pas de champs cerveau et cœur . Ces champs sont "hérités" de la Animalclasse de base. La classe qui hérite a accès aux champs de la classe de base , ils sont donc visibles dans notre Catclasse. Par conséquent, nous n'avons pas besoin de dupliquer ces champs dans la Catclasse. Nous pouvons les retirer de la Animalclasse. De plus, nous pouvons appeler explicitement le constructeur de la classe de base dans le constructeur de la classe enfant. Une classe de base est aussi appelée " superclasse ". C'est pourquoi Java utilise le mot clé super pour indiquer la classe de base. 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 dans notre classe parent. Nous n'avons pas vraiment à faire ça. Il suffit d'appeler le constructeur de la classe parent et de passer les arguments 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 Catconstructeur, nous avons appelé le Animalconstructeur et transmis deux champs. Nous n'avions qu'un seul champ à initialiser explicitement : tail , qui n'est pas dans Animal. Rappelez-vous que nous avons mentionné que le constructeur de la classe parent est appelé en premier lorsqu'un objet est créé ? C'est pourquoi super() doit toujours être le premier dans un constructeur ! Sinon, la logique du constructeur sera violé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 lorsqu'un objet d'une classe enfant est créé, le constructeur de la classe de base est appelé en premier. Et si vous essayez de modifier manuellement ce comportement, le compilateur ne le permettra pas.

Comment un objet est créé

Nous avons précédemment regardé un exemple avec une classe de base et une classe parente : Animaland Cat. En utilisant ces deux classes comme exemples, nous allons maintenant examiner le processus de création d'un objet et d'initialisation des variables. Nous savons qu'il existe des variables statiques et d'instance (non statiques) . Nous savons également que la Animalclasse de base a des variables et que la Catclasse enfant a les siennes. Pour plus de clarté, nous ajouterons une variable statique à chacune des classes Animalet Cat. La variable animalCountAnimal de la classe représentera le nombre total d'espèces animales sur Terre, et la variable catCountvariable signifiera le nombre d'espèces de chats. De plus, nous attribuerons des valeurs de départ à toutes les variables non statiques dans les deux classes (qui seront ensuite modifiées dans le constructeur).

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");
   }
}
Nous créons donc une nouvelle instance de la Catclasse, qui hérite de Animal. Nous avons ajouté une sortie de console détaillée pour voir ce qui se passe et dans quel ordre. Voici ce qui s'affichera lors Catde la création d'un objet : Le constructeur de la classe de base Animal est en cours d'exécution Les variables de la classe Animal ont-elles déjà été initialisées ? Valeur actuelle de la variable statique animalCount = 7700000 Valeur actuelle de brain dans la classe Animal = Valeur initiale de brain dans la classe Animal Valeur actuelle de heart dans la classe Animal = Valeur initiale de heart dans la classe Animal Avoir déjà les variables de la classe Cat été initialisé ? La valeur actuelle de la variable statique catCount = 37 Le constructeur de la classe de base animale est terminé ! Valeur actuelle de brain = Brain Valeur actuelle heart = Heart Le constructeur de la classe cat a démarré (le constructeur Animal est déjà terminé) Valeur actuelle de la variable statique catCount = 37 Valeur actuelle de tail = Valeur initiale de tail dans la classe Cat Valeur actuelle de tail = Queue Ainsi, nous pouvons maintenant voir clairement l'ordre d'initialisation des variables et des appels de constructeur lorsqu'un nouvel objet est créé :
  1. Les variables statiques de la classe de base ( Animal) sont initialisées. Dans notre cas, la Animalvariable animalCount de la classe est définie sur 7700000.

  2. Les variables statiques de la classe enfant ( Cat) sont initialisées.

    Remarque : nous sommes toujours dans le Animalconstructeur et nous avons déjà affiché :

    Le constructeur de la classe de base Animal est en cours d'exécution
    Les variables de la classe Animal ont-elles déjà été initialisées ?
    Valeur actuelle de la variable statique animalCount = 7700000
    Valeur actuelle de brain dans la classe Animal = Valeur initiale de brain dans la classe Animal
    Valeur actuelle de heart dans la classe Animal = Valeur initiale de heart dans la classe Animal
    Avoir déjà les variables de la classe Cat été initialisé ?
    Valeur actuelle de la variable statique catCount = 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 dans le constructeur. Le constructeur Animal n'est pas encore terminé, mais les valeurs initiales de cerveau et de cœur ont déjà été attribuées :

    Le constructeur de la classe de base Animal est en cours d'exécution
    Les variables de la classe Animal ont-elles déjà été initialisées ?
    Valeur actuelle de la variable statique animalCount = 7700000
    Valeur actuelle du cerveau dans la classe Animal = Valeur initiale du cerveau dans la classe Animal
    Valeur actuelle du cœur dans la classe Animal = Valeur initiale du cœur dans la classe Animal


  4. Le constructeur de la classe de base démarre.
    Nous nous sommes déjà convaincus que cette étape est la quatrième : dans les trois premières étapes au début du Animalconstructeur, de nombreuses variables ont déjà reçu des valeurs.


  5. Les champs non statiques de la classe enfant ( Cat) sont initialisés.
    Cela se produit avant que le Catconstructeur ne commence à s'exécuter.
    Lorsqu'il commence à s'exécuter, la variable tail a déjà une valeur :

    Le constructeur de la classe cat a démarré (le constructeur Animal est déjà terminé) Valeur actuelle de la variable statique catCount = 37 Valeur actuelle de tail = Valeur initiale de tail dans la classe Cat


  6. Le constructeur de la Catclasse enfant s'appelle

    Et voilà à quoi ressemble la création d'un objet en Java !

    Je dois dire que nous ne sommes pas de grands fans de l'apprentissage par cœur, mais il est préférable de mémoriser l'ordre d'initialisation des variables et des appels de constructeur .

    Cela augmentera considérablement votre compréhension du déroulement du programme et de l'état de vos objets à un moment donné.

    De plus, de nombreuses classes n'utilisent pas l'héritage. Dans ce cas, les étapes liées à la classe de base ne s'appliquent pas.

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