Polymorphisme
Introduction
Le polymorphisme est un concept de la programmation orientée objet. C'est la capacité d'un objet d'opter pour le type d'un de ces parents sans changer son comportement.
Il permet à une instance de :
- Changer de type par un type parent.
- Être vues et manipulées par les autres classes comme un type parent.
- Conserver le comportement initial de la classe malgré le changement de type.
- Faire du faible couplage
Note
La notion de hiérarchie de classe doit être respectée !
Cas d'usage
Considérons les classes suivantes :
package fr.zelmoacademy.sample;
import java.time.LocalDate;
import java.time.Period;
public abstract class Pet {
protected String name;
protected Float size;
protected Float weight;
protected LocalDate birthDate;
protected Pet() {
}
public abstract void talk();
public void sleep() {
System.out.println("...zzz...");
}
public final Period getAge(){
return Period.between(LocalDate.now(), birthDate);
}
}
package fr.zelmoacademy.sample;
public class Cat extends Pet {
public Cat() {
}
@Override
public void talk() {
System.out.println("Meow");
}
@Override
public void sleep() {
System.out.println("Purrr");
}
public void huntMice() {
// ...
}
}
package fr.zelmoacademy.sample;
public class Dog extends Pet {
public Dog() {
}
@Override
public void talk() {
System.out.println("Woof");
}
@Override
public void sleep() {
super.sleep(); // Combine l'appel de la classe parent
System.out.println("Zzz"); // ET l'appel de la classe enfant.
} //> Sortie Console:
// ...zzz...
// Zzz
public void sniff() {
// ...
}
}
Mise en œuvre
Déclaration classique :
Cat tom = new Cat();
// tom est de type 'Cat'.
// Toutes les méthodes de la classe 'Cat' sont accessibles.
Dog spike = new Dog();
// spike est de type 'Dog'.
// Toutes les méthodes de la classe 'Dog' sont accessibles.
// Variante en Java 10 avec l'inférence de type:
var tom = new Cat();
var spike = new Dog();
Déclaration polymorphique :
Pet tom = new Cat();
// tom est de type 'Cat'.
// Uniquement les méthodes de la classe 'Pet' sont accessibles.
Pet spike = new Dog();
// tom est de type 'Dog'.
// Uniquement les méthodes de la classe 'Pet' sont accessibles.
Faible couplage :
// Cette méthode peut prendre en paramètre des objets de type 'Pet' ou enfant de 'Pet'.
// C'est à dire 'Cat' ou 'Dog'
public void ownerAskPet(Pet anyPet){
anyPet.talk();
}
Cette méthode veut pouvoir demander à un animal de compagnie de parler, mais quel que soit l'animal en question. De plus, la réponse de l'animal se doit d'être spécifique au type réel.
Cat tom = new Cat();
ownerAskPet(tom); // Sortie console: 'Meow'
Dog spike = new Dog();
ownerAskPet(spike); // Sortie console: 'Woof'
// Variante Java 10
var sylvestre = new Cat();
ownerAskPet(sylvestre); // Sortie console: 'Meow'
Transtypage
Le polymorphisme permet de naturellement type une classe dans sa hiérarchie montante.
Le transtypage permet de forcer le type d'un objet vers un objet.
Il faut être prudent lors de son usage car le compilateur Java n'est pas en mesure de vérifier le typage.
Si le typage est faux, à l'exécution du programme vous aurez une erreur de type : java.lang.ClassCastException
.
Note
En Java le transtypage est aussi connu sous le nom de //cast//.
Pet tom = new Cat(); // tom est en réalité de type 'Cat'.
tom.talk(); // Méthode existante dans la classe 'Pet' OK.
tom.huntMice();
^^^^^^^^^^------- // Erreur de compilation:
// méthode inexistante dans la classe 'Pet'.
// transtypage:
Cat tomCat = (Cat) tom;
tomCat.huntMice(); // Méthode existante dans la classe 'Cat' OK.
// transtypage:
Dog tomDog = (Dog) tom;
^^^----- // Erreur d'exécution: 'java.lang.ClassCastException'
// tom n'a pas de lien avec la classe 'Dog'.
Note
Le transtypage est du polymorphisme non naturel ! Soyez très prudent lors de son usage, si possible éviter de l'utiliser abusivement.