Qu'est-ce que le polymorphisme ?
Le polymorphisme est un concept fondamental de la programmation orientee objet (POO) qui permet a un meme element (methode, operateur, objet) de se comporter differemment selon le contexte. Le terme vient du grec "poly" (plusieurs) et "morphe" (forme). En pratique, le polymorphisme permet d'ecrire du code generique qui fonctionne avec des objets de types differents.
Types de polymorphisme
Polymorphisme de sous-typage (heritage)
Le plus courant en POO. Une classe enfant peut redefinir (override) une methode de sa classe parente. Quand on appelle cette methode sur une reference du type parent, c'est la version de l'enfant qui s'execute. C'est le mecanisme de dispatch dynamique (virtual method table). Exemple : une methode calculerSurface() sur une classe Forme sera implementee differemment par Cercle et Rectangle.
Polymorphisme parametrique (generiques)
Les generiques (ou templates en C++) permettent d'ecrire des fonctions et classes qui fonctionnent avec n'importe quel type. Exemple : une liste generique List
Polymorphisme ad hoc (surcharge)
La surcharge de methodes permet plusieurs methodes avec le meme nom mais des parametres differents. La surcharge d'operateurs permet de redefinir le comportement des operateurs (+, -, ==) pour des types personnalises. Le compilateur choisit la bonne version a la compilation (dispatch statique).
Polymorphisme dans les langages modernes
En Java et C#, le polymorphisme repose sur l'heritage de classes et l'implementation d'interfaces. En Python, le duck typing offre un polymorphisme implicite (si un objet a les bonnes methodes, il est accepte). En Go, les interfaces implicites fournissent un polymorphisme structurel. En Rust, les traits et les generiques offrent un polymorphisme sans cout runtime (monomorphisation). En TypeScript, les unions de types et les generiques combinent polymorphisme structurel et parametrique.
Bonnes pratiques
Le polymorphisme est la base du principe Open/Closed (SOLID) : le code est ouvert a l'extension mais ferme a la modification. Preferer la composition a l'heritage excessif. Utiliser les interfaces pour definir les contrats plutot que les classes abstraites. Le pattern Strategy est un exemple classique d'utilisation du polymorphisme pour rendre le comportement interchangeable.