Qu'est-ce que le polymorphisme ?
En programmation, le polymorphisme est la capacité d'un même morceau de code, comme un appel de fonction ou un nom de méthode, à fonctionner avec des valeurs de types différents, chaque type fournissant son propre comportement. Appeler shape.area() lance un calcul différent pour un cercle et pour un carré.
Mis à jour le 24 septembre 2026
En Python, len("hello") renvoie 5, len([4, 8, 15]) renvoie 3, et len({"a": 1}) renvoie 1. C'est un seul nom de fonction utilisé sur trois types, et chaque type compte à sa façon : une chaîne compte ses caractères, une liste ses éléments, un dictionnaire ses clés. Le mot vient du grec : poly, plusieurs, et morphê, forme. Un seul appel, plusieurs formes de comportement.
Comment fonctionne le polymorphisme
Le code appelle une méthode par son nom, comme shape.area(). Quand cette ligne s'exécute, le langage regarde l'objet réel et cherche area dans la classe propre de cet objet. Cette recherche s'appelle la liaison dynamique (dynamic dispatch), et c'est elle qui permet à une seule ligne de faire un travail différent pour des objets différents :
Circle 3.14
Square 9
Circle 12.57
Python trouve la méthode en cherchant d'abord dans la classe de l'objet, puis dans ses classes parentes selon un ordre fixe appelé ordre de résolution des méthodes (method resolution order). Si Square n'avait pas son propre area(), la recherche atteindrait Shape.area() et lèverait NotImplementedError, un signal que chaque sous-classe doit en fournir un.
La boucle ne vérifie jamais quel genre de forme elle contient. Pour ajouter un triangle, tu écris une classe Triangle avec son propre area(), et la boucle fonctionne sans changement. Sans polymorphisme, la boucle aurait besoin d'une branche if isinstance(...) pour chaque forme, à modifier chaque fois qu'une nouvelle apparaît.
Les types de polymorphisme
| Type | Autres noms | À quoi il ressemble | Quand la version est choisie |
|---|---|---|---|
| Par sous-typage | Polymorphisme dynamique, redéfinition de méthode | Une sous-classe remplace une méthode de son parent | Pendant l'exécution du programme |
| Ad hoc | Surcharge | Un nom, plusieurs versions pour des types de paramètres différents ; aussi la surcharge d'opérateurs | À la compilation en Java et en C++ |
| Paramétrique | Génériques, templates | Un morceau de code qui marche pour n'importe quel type : List<T> en Java, vector<T> en C++ | À la compilation |
Quand on parle de « polymorphisme » en programmation orientée objet sans plus de précision, on veut presque toujours dire la première ligne : le polymorphisme par sous-typage, via la redéfinition.
Python a les trois à sa manière. La redéfinition fonctionne comme dans l'exemple des formes. Les opérateurs comme + relèvent du polymorphisme ad hoc. Des fonctions comme max() et sorted() sont paramétriques dans l'esprit : elles acceptent une liste de nombres, de chaînes ou de dates, tant que les éléments peuvent être comparés, et des annotations de type comme list[int] ou un TypeVar peuvent l'indiquer explicitement.
Polymorphisme statique et dynamique en Java
Java a les deux sortes, et les questions d'entretien portent souvent sur la différence :
class Animal { String sound() { return "..."; } }
class Dog extends Animal {
@Override String sound() { return "Woof"; }
}
Animal pet = new Dog();
pet.sound(); // "Woof": chosen at run time from the object
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
add(2, 3); // int version, chosen by the compiler
add(2.5, 1.0); // double version
La variable pet a le type Animal, et pourtant c'est la version de Dog qui s'exécute, car le choix dépend de l'objet, pas de la variable. Les deux méthodes add relèvent de la surcharge : le compilateur en choisit une d'après les types des arguments, avant que le programme ne s'exécute. Les interfaces donnent le même comportement à l'exécution sans partager de code : toute classe qui implémente Comparable peut être triée par Collections.sort. Le C++ fonctionne de la même façon, à une différence près : une méthode n'a de liaison dynamique que si elle est déclarée virtual. Voir le polymorphisme en Java, la surcharge de méthodes et les fonctions virtuelles en C++.
Le polymorphisme en Python : duck typing et opérateurs
Python n'exige pas de classe parente commune. Si un objet a la méthode que le code appelle, ça marche : « si ça marche comme un canard et que ça cancane comme un canard, c'est un canard ». Les opérateurs sont eux aussi polymorphes. Écrire a + b appelle a.__add__(b), donc tes propres classes peuvent prendre en charge +, len() et print() :
3 abcd [1, 2]
Vector(11, 22)
5 3 2
L'héritage est un moyen d'obtenir du polymorphisme, pas une obligation. Vector n'hérite de rien de particulier, et pourtant len() et + le traitent comme un type intégré. La documentation Python sur l'héritage montre la voie des sous-classes.
Erreurs fréquentes
Croire que Python surcharge selon la signature. Un second def avec le même nom remplace le premier sans rien dire :
Hi Ana Silva
Traceback (most recent call last):
...
TypeError: greet() missing 1 required positional argument: 'last'
Utilise plutôt un argument par défaut : def greet(first, last="").
Oublier virtual en C++. Sans lui, appeler une méthode via un pointeur vers la classe de base exécute la version de base, même quand l'objet est une sous-classe.
Des redéfinitions qui changent le sens. Si area() renvoie le périmètre dans une sous-classe, chaque appelant qui fait confiance à area() se retrouve cassé. Une redéfinition doit tenir la promesse faite par le parent ; cette règle s'appelle le principe de substitution de Liskov.
Des vérifications de type partout. Une chaîne de branches if type(x) == ... est généralement le signe que chaque type devrait plutôt porter sa propre méthode.
Pour aller plus loin
Le polymorphisme fonctionne avec l'encapsulation, qui protège les données de chaque objet, et l'abstraction, qui définit l'interface commune que les types implémentent. Entraîne-toi à la redéfinition avec la documentation Python sur les classes, ou essaie le cours Java, où surcharge et redéfinition apparaissent côte à côte.
Questions fréquentes
Quel est un exemple de polymorphisme ?
+ en Python : 1 + 2 additionne des nombres, "ab" + "cd" concatène des chaînes et [1] + [2] concatène des listes. Le même symbole fonctionne sur trois types, et chaque type décide de ce qu'il signifie. En code orienté objet, l'exemple classique est une liste de formes où chacune répond à area() avec sa propre formule.Quelle est la différence entre polymorphisme et héritage ?
Qu'est-ce que le polymorphisme en biologie ?
Python permet-il la surcharge de méthodes ?
def avec le même nom remplace le premier. Le code Python obtient le même effet avec des arguments par défaut, *args, ou functools.singledispatch, qui choisit une fonction selon le type du premier argument.À quoi sert le polymorphisme ?
shape.draw() sur chaque forme n'a besoin d'aucune modification quand tu ajoutes une classe triangle ; seule la nouvelle classe est écrite. Sans polymorphisme, cette boucle gagnerait une nouvelle branche if pour chaque type.