Animal
(animal) :
public class Animal {
String name;
int age;
}
On peut créer pour cela, par exemple, 2 classes descendantes - Cat
et 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, Cat
le constructeur de classe fonctionnera en premier Animal
, et ensuite seulement le constructeur Cat
. Pour nous en assurer, ajoutons aux constructeurs Cat
et Animal
sortons 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 brain
de heart
la classe parent Animal
, ainsi qu'un champ tail
dans 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 Cat
n'ait pas de champs brain
et 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, Cat
ils sont donc visibles dans notre classe. Par conséquent, nous n'avons pas besoin Cat
de 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, Cat
nous avons appelé le constructeur Animal
et lui avons transmis deux champs. Nous n'avons qu'à initialiser explicitement un champ - tail
qui Animal
n'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 -Animal
et 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 Animal
a ses propres variables et que la classe descendante Cat
a les siennes. Ajoutons une variable statique à la classe pour Animal
plus de clarté . Cat
La variable animalCount
de classe Animal
serait le nombre total d’espèces animales sur terre, et la variable catsCount
serait 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 Cat
hé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 :
-
Les variables statiques de la classe de base ( ) sont initialisées
Animal
. Dans notre cas, la variableanimalCount
de classeAnimal
reçoit la valeur 7700000. -
Les variables statiques de la classe descendante ( ) sont initialisées
Cat
. Faites attention, nous sommes toujours à l'intérieur du constructeurAnimal
et 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
-
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
Animal
n'a pas encore terminé ses travaux, mais les valeurs initialesbrain
ontheart
déjà été attribuées :Выполняется конструктор базового класса Animal Были ли уже проинициализированы переменные класса Animal? Текущее meaning статической переменной animalCount = 7700000 Текущее meaning brain в классе Animal = Изначальное meaning brain в классе Animal Текущее meaning heart в классе Animal = Изначальное meaning heart в классе Animal
-
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,
Animal
de nombreuses variables ont déjà reçu des valeurs. -
Initialisation des champs non statiques d'une classe enfant (
Cat
).Cela se produit avant que le concepteur
Cat
ne commence à travailler.Au moment où il a commencé à travailler, la variable
tail
avait déjà une valeur :Конструктор класса Cat начал работу (конструктор Animal уже был выполнен) Текущее meaning статической переменной catsCount = 37 Текущее meaning tail = Изначальное meaning tail в классе Cat
-
Le constructeur de la classe descendante est appelé
Cat
GO TO FULL VERSION