6.3Polymorphisme dans une hiérarchie d'objets
6.3 – Polymorphisme dans une hiérarchie d'objets
Le polymorphisme permet de traiter différents types d'objets de manière uniforme grâce à une référence commune (la classe mère). Un objet peut être référencé par le type de sa classe mère, ce qui permet un traitement polymorphique où la méthode appropriée est appelée selon le type réel de l'objet.
🔑 Principe du polymorphisme
En Java, une variable de type classe mère peut référencer un objet de n'importe quelle classe fille. À l'exécution, Java détermine automatiquement quelle méthode appeler en fonction du type réel de l'objet (pas du type de la variable).
Exemple : Polymorphisme de base
// Hiérarchie de classes
public class Personne {
public void sePresenter() {
System.out.println("Je suis une personne");
}
}
public class Etudiant extends Personne {
@Override
public void sePresenter() {
System.out.println("Je suis un étudiant");
}
}
public class Professeur extends Personne {
@Override
public void sePresenter() {
System.out.println("Je suis un professeur");
}
}
// Utilisation polymorphique
Personne p1 = new Personne();
Personne p2 = new Etudiant(); // Référence de type Personne, objet de type Etudiant
Personne p3 = new Professeur(); // Référence de type Personne, objet de type Professeur
p1.sePresenter(); // Affiche : Je suis une personne
p2.sePresenter(); // Affiche : Je suis un étudiant (polymorphisme)
p3.sePresenter(); // Affiche : Je suis un professeur (polymorphisme)
📦 Polymorphisme avec des tableaux
Le polymorphisme est particulièrement utile avec les collections (tableaux, listes) où vous pouvez stocker différents types d'objets sous une référence commune.
Exemple : Tableau polymorphique
// Créer un tableau de Personne
Personne[] personnes = new Personne[4];
// Stocker différents types d'objets
personnes[0] = new Personne();
personnes[1] = new Etudiant();
personnes[2] = new Professeur();
personnes[3] = new Etudiant();
// Traiter tous les objets de manière uniforme
for (Personne p : personnes) {
p.sePresenter(); // Appelle la méthode appropriée selon le type réel
}
// Affiche :
// Je suis une personne
// Je suis un étudiant
// Je suis un professeur
// Je suis un étudiant
🔄 Polymorphisme avec des listes
Le polymorphisme fonctionne également avec les collections Java comme les listes.
Exemple : Liste polymorphique
import java.util.ArrayList;
import java.util.List;
List<Personne> personnes = new ArrayList<>();
personnes.add(new Personne());
personnes.add(new Etudiant());
personnes.add(new Professeur());
// Parcourir et traiter polymorphiquement
for (Personne p : personnes) {
p.sePresenter();
}
⚙️ Liaison dynamique (Dynamic Binding)
Le polymorphisme en Java utilise la liaison dynamique (ou late binding). Cela signifie que la méthode appelée est déterminée à l'exécution en fonction du type réel de l'objet, pas du type de la variable.
Exemple : Liaison dynamique
public class Animal {
public void faireDuBruit() {
System.out.println("L'animal fait du bruit");
}
}
public class Chien extends Animal {
@Override
public void faireDuBruit() {
System.out.println("Wouf wouf !");
}
}
public class Chat extends Animal {
@Override
public void faireDuBruit() {
System.out.println("Miaou !");
}
}
// Liaison dynamique
Animal animal1 = new Chien(); // Type de variable : Animal, Type réel : Chien
Animal animal2 = new Chat(); // Type de variable : Animal, Type réel : Chat
animal1.faireDuBruit(); // Appelle la méthode de Chien (type réel)
animal2.faireDuBruit(); // Appelle la méthode de Chat (type réel)
🎯 Avantages du polymorphisme
- Code réutilisable : Traiter différents types d'objets de manière uniforme
- Extensibilité : Ajouter de nouvelles classes sans modifier le code existant
- Maintenabilité : Code plus simple et plus facile à maintenir
- Flexibilité : Permet de changer l'implémentation sans affecter le code client
📊 Exemple complet : Système de gestion
Exemple : Système de gestion d'employés
public class Employe {
protected String nom;
protected double salaire;
public Employe(String nom, double salaire) {
this.nom = nom;
this.salaire = salaire;
}
public void travailler() {
System.out.println(nom + " travaille");
}
public double calculerSalaire() {
return salaire;
}
}
public class Developpeur extends Employe {
public Developpeur(String nom, double salaire) {
super(nom, salaire);
}
@Override
public void travailler() {
System.out.println(nom + " développe du code");
}
}
public class Manager extends Employe {
public Manager(String nom, double salaire) {
super(nom, salaire);
}
@Override
public void travailler() {
System.out.println(nom + " gère une équipe");
}
@Override
public double calculerSalaire() {
return salaire * 1.2; // Bonus de 20%
}
}
// Utilisation polymorphique
public class GestionEmployes {
public static void main(String[] args) {
Employe[] employes = {
new Developpeur("Alice", 5000),
new Manager("Bob", 7000),
new Developpeur("Charlie", 5500)
};
// Traiter tous les employés de manière uniforme
for (Employe e : employes) {
e.travailler(); // Polymorphisme : méthode appropriée selon le type
System.out.println("Salaire : " + e.calculerSalaire());
System.out.println("---");
}
}
}
⚠️ Limitations du polymorphisme
Il est important de comprendre que le polymorphisme fonctionne uniquement pour les méthodes. Les attributs ne sont pas polymorphiques.
- Le polymorphisme fonctionne pour les méthodes (redéfinies)
- Les attributs ne sont pas polymorphiques : l'attribut utilisé est celui du type de la variable, pas du type réel
- Les méthodes
staticetfinalne peuvent pas être redéfinies, donc pas de polymorphisme
Exemple : Attributs non polymorphiques
public class Parent {
String nom = "Parent";
public void afficher() {
System.out.println("Nom : " + nom);
}
}
public class Enfant extends Parent {
String nom = "Enfant"; // Masque l'attribut de Parent
@Override
public void afficher() {
System.out.println("Nom : " + nom);
}
}
// Utilisation
Parent p = new Enfant();
System.out.println(p.nom); // Affiche : Parent (attribut non polymorphique)
p.afficher(); // Affiche : Nom : Enfant (méthode polymorphique)
💡 Points clés à retenir
- Référence commune : Un objet peut être référencé par le type de sa classe mère
- Liaison dynamique : La méthode appelée est déterminée à l'exécution selon le type réel
- Collections : Permet de stocker différents types d'objets dans une même collection
- Extensibilité : Facilite l'ajout de nouvelles classes sans modifier le code existant
- Méthodes uniquement : Le polymorphisme fonctionne pour les méthodes, pas pour les attributs
- Utilisez le polymorphisme pour créer du code générique qui fonctionne avec différentes classes
- Le polymorphisme est particulièrement utile avec les collections (listes, tableaux)
- Assurez-vous que les méthodes sont redéfinies (pas seulement héritées) pour bénéficier du polymorphisme
- Évitez d'accéder directement aux attributs via une référence parente si vous voulez un comportement polymorphique