Animal
classe parent, qui représente les animaux, et créons- speak
y une méthode :
public class Animal {
public void speak() {
System.out.println("Hello!");
}
}
Bien que nous ayons tout juste commencé à écrire notre programme, vous pouvez probablement voir un problème potentiel : le monde regorge d'animaux, et ils "parlent" tous différemment : les chats miaulent, les canards cancanent, les serpents sifflent, etc. Notre objectif est simple : nous veulent éviter de créer un tas de méthodes pour parler. Au lieu de créer une meow()
méthode pour miauler, hiss()
pour siffler, etc., nous voulons que le serpent siffle, que le chat miaule et que le chien aboie lorsque la speak()
méthode est appelée. Nous pouvons facilement y parvenir en utilisant la méthode overriding . Wikipedia explique le terme comme suit : Remplacer la méthode, dans la programmation orientée objet, est une fonctionnalité de langage qui permet à une sous-classe ou à une classe enfant de fournir une implémentation spécifique d'une méthode déjà fournie par l'une de ses superclasses ou classes parentes. C'est fondamentalement correct. La redéfinition vous permet de prendre une méthode d'une classe parente et d'écrire votre propre implémentation dans chaque classe dérivée. La nouvelle implémentation dans la classe enfant "remplace" celle du parent. Voyons à quoi cela ressemble avec un exemple. Créons 4 descendants de notre Animal
classe :
public class Bear extends Animal {
@Override
public void speak() {
System.out.println("Growl!");
}
}
public class Cat extends Animal {
@Override
public void speak() {
System.out.println("Meow!");
}
}
public class Dog extends Animal {
@Override
public void speak() {
System.out.println("Woof!");
}
}
public class Snake extends Animal {
@Override
public void speak() {
System.out.println("Hiss!");
}
}
Voici une petite astuce pour le futur : pour remplacer les méthodes d'une classe parente, accédez au code de la classe dérivée dans IntelliJ IDE , appuyez sur Ctrl+O et sélectionnez Remplacer les méthodes... dans le menu. Habituez-vous à utiliser les raccourcis clavier dès le départ. Ils accéléreront le codage ! Pour obtenir le comportement souhaité, nous avons fait quelques choses :
- Dans chaque classe descendante, nous avons créé une méthode portant le même nom que la méthode de la classe parent.
-
Nous avons dit au compilateur que nous ne donnions pas seulement à la méthode le même nom que dans la classe parente, mais que nous voulions plutôt remplacer son comportement. Ce "message" au compilateur est transmis via l' annotation @Override .
L'annotation @Override au-dessus d'une méthode indique au compilateur (ainsi qu'aux autres programmeurs lisant votre code) : "Ne vous inquiétez pas. Ce n'est pas une erreur ou un oubli. Je suis conscient que cette méthode existe déjà et je veux la remplacer . - Nous avons écrit l'implémentation dont nous avons besoin pour chaque classe descendante. Lorsque la
speak()
méthode est appelée, un serpent 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.speak();
animal2.speak();
animal3.speak();
animal4.speak();
}
}
Sortie console :
Woof!
Meow!
Growl!
Hiss!
Super, tout fonctionne comme il se doit ! Nous avons créé 4 variables de référence dont le type est la Animal
classe mère, et leur avons assigné 4 objets différents des classes descendantes. En conséquence, chaque objet se comporte différemment. Pour chacune des classes dérivées, la speak()
méthode surchargée remplace la méthode existante speak()
de la Animal
classe (qui affiche simplement « Parlant : » sur la console). Le remplacement de méthode a plusieurs limites :
-
Une méthode redéfinie doit avoir les mêmes arguments que la méthode de la classe parent.
Si la
speak
méthode de la classe parent prend aString
comme entrée, alors la méthode redéfinie dans la classe descendante doit également prendre aString
comme entrée. Sinon, le compilateur générera une erreur :public class Animal { public void speak(String s) { System.out.println("Speaking: " + s); } } public class Cat extends Animal { @Override // Error! public void speak() { System.out.println("Meow!"); } }
-
La méthode redéfinie doit avoir le même type de retour que la méthode de la classe parent.
Sinon, nous aurons une erreur de compilation :
public class Animal { public void speak() { System.out.println("Hello!"); } } public class Cat extends Animal { @Override public String speak() { // Error! System.out.println("Meow!"); return "Meow!"; } }
-
Le modificateur d'accès de la méthode remplacée ne peut pas non plus différer de celui d'origine :
public class Animal { public void speak() { System.out.println("Hello!"); } } public class Cat extends Animal { @Override private void speak() { // Error! System.out.println("Meow!"); } }
speak()
méthode pour tout le monde plutôt qu'un tas de méthodes différentes, par exemple bark()
, meow()
, etc.