« Fais ton cri »
Demandez à un chat, un chien et un coq de « faire leur cri » : chacun répond à sa manière. La demande est la même, la réponse dépend de l'animal.
for animal in [Chat(), Chien(), Coq()]:
animal.crier() # Miaou / Ouaf / Cocorico Redéfinir une méthode dans une classe fille, traiter des objets différents de façon uniforme, et surcharger les méthodes et les opérateurs en Python.
Un atelier de menuiserie à Tétouan calcule la surface de bois nécessaire pour ses commandes : des plateaux rectangulaires, des tables rondes, des étagères triangulaires. Le programme doit parcourir toutes les pièces d'une commande et additionner leurs aires, sans écrire un « si c'est un cercle alors... sinon si c'est un rectangle... ». C'est exactement ce que permet le polymorphisme.
La commande contient trois pièces de classes différentes. La boucle appelle piece.aire() sur chacune.
Polymorphisme veut dire « plusieurs formes ». Un même appel, piece.aire(), déclenche un calcul différent selon la classe réelle de l’objet.
Une classe fille peut redéfinir (override) une méthode héritée : elle écrit une méthode de même nom qui remplace celle de la mère. Pour réutiliser la version de la mère, on appelle super().methode().
for piece in commande:
total += piece.aire() # Rectangle.aire() ou Disque.aire()
Ajouter une nouvelle sorte de pièce ne demande aucune modification de la boucle : c’est l’intérêt principal du polymorphisme.
En Java ou en C#, on peut écrire plusieurs méthodes de même nom avec des paramètres différents. En Python, la dernière définie gagne. On obtient le même résultat avec des paramètres par défaut :
def aire(self, unite="m2"):
...
Python appelle des méthodes spéciales quand on utilise un opérateur sur un objet :
| Écriture | Méthode appelée |
|---|---|
a + b | a.__add__(b) |
a == b | a.__eq__(b) |
a < b | a.__lt__(b) |
print(a) | a.__str__() |
len(a) | a.__len__() |
En les définissant, vos objets s’utilisent aussi naturellement que des nombres ou des chaînes.
Demandez à un chat, un chien et un coq de « faire leur cri » : chacun répond à sa manière. La demande est la même, la réponse dépend de l'animal.
for animal in [Chat(), Chien(), Coq()]:
animal.crier() # Miaou / Ouaf / Cocorico En Python, + additionne des nombres, colle des textes et fusionne des listes. C'est déjà du polymorphisme : le même opérateur se comporte selon le type.
print(2 + 3) # 5 print("Dar" + "ija") # Darija print([1, 2] + [3]) # [1, 2, 3]
Exécutez le code : les objets et leurs attributs s'afficheront ici.
Ajoutez la classe Triangle(nom, base, hauteur) avec sa méthode aire(). Vérifiez que la boucle de la commande fonctionne sans modification.
class Triangle(Piece): def __init__(self, nom, base, hauteur): super().__init__(nom) self.base, self.hauteur = base, hauteur def aire(self): return self.base * self.hauteur / 2 commande.append(Triangle("Équerre", 0.4, 0.4))
Écrivez une classe Prix(montant) dont les objets s'additionnent avec + et se comparent avec <. Testez Prix(20) + Prix(15) et Prix(20) < Prix(15).
Les méthodes spéciales s'appellent __add__ et __lt__.
class Prix: def __init__(self, montant): self.montant = montant def __add__(self, autre): return Prix(self.montant + autre.montant) def __lt__(self, autre): return self.montant < autre.montant def __str__(self): return f"{self.montant} DH" print(Prix(20) + Prix(15)) # 35 DH print(Prix(20) < Prix(15)) # False
Dans une classe Taxi(Voiture), redéfinissez decrire() pour ajouter « (taxi) » à la description de la classe mère, sans la recopier.
class Taxi(Voiture): def decrire(self): return super().decrire() + " (taxi)"