Héritage, polymorphisme et composition
extends, polymorphisme, et quand composer.
Objectifs
À la fin de cette leçon, vous saurez :
- utiliser extends et super pour l'héritage ;
- expliquer le polymorphisme par un exemple concret ;
- savoir quand préférer la composition à l'héritage.
L'héritage : extends
class Utilisateur {
constructor(nom) {
this.nom = nom;
}
saluer() {
return `Bonjour ${this.nom}`;
}
}
class Admin extends Utilisateur {
constructor(nom) {
super(nom); // appelle le constructeur parent
this.role = "ADMIN";
}
supprimerTout() { ... } // ajout propre à Admin
}
const a = new Admin("Ana");
a.saluer(); // hérité d'Utilisateur
a.supprimerTout(); // propre à Admin
extends crée la chaîne de prototypes : Admin → Utilisateur. super() est obligatoire avant d'utiliser this dans un constructeur enfant.
Le polymorphisme : même appel, comportements différents
class Rendu {
texte() { return "..."; }
}
class TacheVue extends Rendu {
texte() { return `[${this.fait ? "x" : " "}] ${this.titre}`; }
}
class UserVue extends Rendu {
texte() { return this.nom.toUpperCase(); }
}
function afficherTout(elements) {
for (const e of elements) console.log(e.texte()); // chacun le sien
}
afficherTout ne connaît pas les classes précises : elle demande .texte() et chaque objet répond à SA manière. C'est le polymorphisme — et c'est exactement ce que fera votre future interface Angular avec ses composants interchangeables.
La composition : construire par assemblage
Alternative à « Est-un » (héritage) : « A-un » (composition).
// Héritage : Admin EXTEND Utilisateur
// Composition : Utilisateur A UN stockage de sessions
class GestionnaireSessions {
creer(userId) { ... }
detruire(sessionId) { ... }
}
class ServiceAuthentification {
constructor(sessions) {
this.sessions = sessions; // injecté, pas hérité
}
}
La règle pragmatique : préférer la composition quand la relation n'est pas vraiment « est un ». Un Admin EST-IL un Utilisateur ? Oui → héritage légitime. Un ServiceAuthentification A-T-IL des sessions ? Oui → composition. Les arbres d'héritage profonds deviennent ingérables ; la composition reste plate et remplaçable.
Exercice
- Créez
Moderateur extends UtilisateuravecverrouillerPublication(). - Faites une liste mixte [Utilisateur, Admin, Moderateur] et appelez saluer() sur tous.
- Refactorez : donnez au ServiceAuthentification sa dépendance GestionnaireSessions via le constructeur.
Résumé
- extends + super = chaîne prototype lisible ; polymorphisme = dispatch automatique.
- « Est-un » → héritage ; « a-un » → composition ; profondeur limitée.
Correction disponibleCherchez d’abord par vous-même.Voir la correction
Correction
Point sur l'exercice 3
Le service ne sait PAS quelle implémentation il reçoit : il exige juste quelque chose qui sait creer/detruire. Demain vous injecterez une version mémoire pour les tests, une version PostgreSQL en prod — sans toucher au service. C'est l'injection de dépendances du chapitre 31, entrevue ici.