Qu'est-ce que le polymorphisme ?
Le polymorphisme est un concept fondamental de la programmation orientee objet (POO) qui permet à un même élément (méthode, opérateur, objet) de se comporter differemment selon le contexte. Le terme vient du grec "poly" (plusieurs) et "morphe" (forme). En pratique, le polymorphisme permet d'écrire du code générique qui fonctionne avec des objets de types différents.
Types de polymorphisme
Polymorphisme de sous-typage (héritage)
Le plus courant en POO. Une classe enfant peut redefinir (override) une méthode de sa classe parente. Quand on appelle cette méthode sur une référence du type parent, c'est la version de l'enfant qui s'execute. C'est le mécanisme de dispatch dynamique (virtual method table). Exemple : une méthode calculerSurface() sur une classe Forme sera implementee differemment par Cercle et Rectangle.
Polymorphisme parametrique (génériques)
Les génériques (ou templates en C++) permettent d'écrire des fonctions et classes qui fonctionnent avec n'importe quel type. Exemple : une liste générique List
Polymorphisme ad hoc (surcharge)
La surcharge de méthodes permet plusieurs méthodes avec le même nom mais des paramètres différents. La surcharge d'opérateurs permet de redefinir le comportement des opérateurs (+, -, ==) pour des types personnalisés. Le compilateur choisit la bonne version à la compilation (dispatch statique).
Polymorphisme dans les langages modernes
En Java et C#, le polymorphisme repose sur l'héritage de classes et l'implémentation d'interfaces. En Python, le duck typing offre un polymorphisme implicite (si un objet à les bonnes méthodes, il est accepte). En Go, les interfaces implicites fournissent un polymorphisme structurel. En Rust, les traits et les génériques offrent un polymorphisme sans coût runtime (monomorphisation). En TypeScript, les unions de types et les génériques combinent polymorphisme structurel et parametrique.
Bonnes pratiques
Le polymorphisme est la base du principe Open/Closed (SOLID) : le code est ouvert à l'extension mais ferme à la modification. Préférer la composition à l'héritage excessif. Utiliser les interfaces pour définir les contrats plutôt que les classes abstraites. Le pattern Strategy est un exemple classique d'utilisation du polymorphisme pour rendre le comportement interchangeable.