Animal
désignant des animaux et créons-y une méthode voice
- « voix » :
public class Animal {
public void voice() {
System.out.println("Voice!");
}
}
Même si nous venons juste de commencer à écrire le programme, vous pouvez très probablement voir le problème potentiel : il y a beaucoup d'animaux dans le monde, et ils « parlent » tous différemment : les chats miaulent, les canards cancanent, les serpents sifflent. Notre objectif est simple : éviter de créer une multitude de méthodes pour voter. Au lieu de créer des méthodes voiceCat()
pour miauler, voiceSnake()
siffler, etc., nous voulons voice()
que le serpent siffle, que le chat miaule et que le chien aboie lorsque la méthode est appelée. Nous pouvons facilement y parvenir en utilisant le mécanisme de substitution de méthode (Override en Java) . Wikipédia donne l'explication suivante du terme « remplacement » : Le remplacement de méthode dans la programmation orientée objet est l'une des fonctionnalités d'un langage de programmation qui permet à une sous-classe ou à une classe enfant de fournir une implémentation spécifique d'une méthode déjà implémentée dans l'une des superclasses. ou des classes de parents. C'est, en général, correct. La substitution vous permet de prendre une méthode d'une classe parent et d'écrire votre propre implémentation de cette méthode dans chaque classe descendante. La nouvelle implémentation « remplacera » le parent dans la classe enfant. Voyons à quoi cela ressemble avec un exemple. Créons 4 classes successeurs pour notre classeAnimal
:
public class Bear extends Animal {
@Override
public void voice() {
System.out.println("Р-р-р!");
}
}
public class Cat extends Animal {
@Override
public void voice() {
System.out.println("Meow!");
}
}
public class Dog extends Animal {
@Override
public void voice() {
System.out.println("Woof!");
}
}
public class Snake extends Animal {
@Override
public void voice() {
System.out.println("Ш-ш-ш!");
}
}
Un petit hack de vie pour le futur : pour remplacer les méthodes de la classe parent, accédez au code de la classe descendante dans Intellij IDE a, appuyez sur Ctrl+O et sélectionnez « Remplacer les méthodes... » dans le menu. Habituez-vous à utiliser les raccourcis clavier dès le début, cela accélérera l'écriture des programmes ! Pour définir le comportement que nous souhaitions, nous avons effectué plusieurs opérations :
- Nous avons créé une méthode dans chaque classe descendante avec le même nom que la méthode de la classe parent.
-
Nous avons dit au compilateur que nous avions nommé la méthode de la même manière que dans la classe parent pour une raison : nous voulions remplacer son comportement. Pour ce « message » au compilateur, nous mettons une annotation @Override sur la méthode .
L'annotation @Override placée au-dessus d'une méthode indique au compilateur (et aux programmeurs qui lisent également votre code) : « Tout va bien, ce n'est pas une erreur ou un oubli de ma part. Je me souviens qu'une telle méthode existe déjà et je souhaite l'ignorer. - Nous avons écrit l'implémentation dont nous avions besoin pour chaque classe descendante. Lorsqu'il est appelé, un serpent
voice()
doit siffler, un ours doit grogner, etc.
public class Main {
public static void main(String[] args) {
Animal animal1 = new Dog();
Animal animal2 = new Cat();
Animal animal3 = new Bear();
Animal animal4 = new Snake();
animal1.voice();
animal2.voice();
animal3.voice();
animal4.voice();
}
}
Sortie de la console : Ouf ! Miaou! Rrrr ! Chut ! Super, tout fonctionne comme il se doit ! Nous avons créé 4 variables de référence de la classe parent Animal
et les avons affectées à 4 objets différents des classes descendantes. En conséquence, chaque objet se comporte différemment. Pour chacune des classes descendantes, la méthode remplacée voice()
a remplacé la méthode « native » voice()
de la classe Animal
(qui affiche simplement « Voice ! » sur la console). La substitution présente un certain nombre de limitations :
-
La méthode remplacée doit avoir les mêmes arguments que la méthode parent.
Si une méthode
voice
dans une classe parent accepte comme inputString
, la méthode substituée dans la classe enfant doit également accepter comme inputString
, sinon le compilateur générera une erreur :public class Animal { public void voice(String s) { System.out.println("Voice! " + s); } } public class Cat extends Animal { @Override//error! public void voice() { System.out.println("Meow!"); } }
-
La méthode remplacée doit avoir le même type de retour que la méthode parent.
Sinon, nous recevrons une erreur de compilation :
public class Animal { public void voice() { System.out.println("Voice!"); } } public class Cat extends Animal { @Override public String voice() { //error! System.out.println("Meow!"); return "Meow!"; } }
-
Le modificateur d'accès d'une méthode surchargée ne peut pas non plus différer de celui « d'origine » :
public class Animal { public void voice() { System.out.println("Voice!"); } } public class Cat extends Animal { @Override private void voice() { //error! System.out.println("Meow!"); } }
voice()
pour tous au lieu d'un tas de méthodes voiceDog()
, voiceCat()
etc.
GO TO FULL VERSION