Surchargez les méthodes en Python
La surcharge désigne le concept selon lequel une classe enfant crée une nouvelle implémentation d’une méthode héritée. Lorsqu’une méthode dans une classe enfant est créée avec le même nom et la même signature qu’une méthode dans le parent, la méthode enfant l’emporte.
En réalité, nous avons utilisé le concept de surcharge une fois ou deux dans les deux chapitres précédents, par exemple avec le ContactSystem
:
Chaque enfant implémente sa propre méthode send(message)
, qui se comporte différemment – elle envoie un SMS, un e-mail, ou un document à l’imprimante.
Et on peut faire cela simplement en écrivant une autre méthode dans la classe enfant ?
C’est aussi simple que ça ! Prenons cet exemple :
from abc import ABC # permet de définir des classes de base
class Shape(ABC):
def area(self):
return 0
class Square(Shape):
def __init__(self, length):
self.length = length
def area(self):
return length * length
Dans cet exemple, Shape
(“Forme”) contient une méthode de superficie qui renvoie l’aire de la forme.Square
(“Carré”) surcharge cette méthode en implémentant la formule pour l’aire d’un carré.
Utilisez des classes abstraites
Bon, je comprends que area()
est surchargé, mais qu’est-ce que c’est que cet ABC
?
ABC signifie « Abstract Base Class », ou « classe de base abstraite ». Il s’agit du mécanisme utilisé par Python pour implémenter ce que l’on nomme une classe abstraite.
Une classe abstraite est une classe qui ne peut pas être instanciée – la seule façon de l’utiliser est de créer une sous-classe. Par exemple, prenons le cas de Shape
("Forme") – qu’est-ce que cela voudrait dire d’avoir un objet Shape
? À quoi est-ce qu’il pourrait bien ressembler ? Nous pourrions faire de Square
, ou Carré, une sous-classe de Shape
, puis utiliser notre Carré. Cette approche nous permettrait d’avoir une classe parent commune pour Cercle, Carré, Triangle, etc., sans laisser personne instancier une Shape
.
Accédez aux méthodes des parents
Bien que la surcharge nous permette de modifier entièrement des comportements hérités, il peut parfois être utile d’avoir accès au code des méthodes des classes parents, depuis les classes enfants.
L’un des emplacements les plus courants pour cette utilisation se trouve dans les constructeurs. Pour cela, nous utilisonssuper()
– comme ceci :
class Drink:
"""Une boisson."""
def __init__(self, price):
"""Initialise un prix."""
self.price = price
def drink(self):
"""Boire la boisson."""
print("Je ne sais pas ce que c'est, mais je le bois.")
class Coffee(Drink):
"""Café."""
prices = {"simple": 1, "serré": 1, "allongé": 1.5}
def __init__(self, type):
"""Initialise le type du café."""
self.type = type
super().__init__(price=self.prices.get(type, 1))
def drink(self):
"""Boire le café."""
print("Un bon café pour me réveiller !")
Dans cet exemple, Coffee
("café") est une sous-classe de Drink
("boisson"). La classe Coffee
possède ses propres tarifs, qu’elle passe au constructeur de Drink
pour initialiser le bon prix !
Est-ce qu’on ne pourrait pas plutôt simplement paramétrer self.price=self.prices.get(type, 1)
dans le constructeur de Coffee
?
Oui, on pourrait, mais cette solution ne peut pas être mise à l’échelle. Imaginez que le constructeur de Drink
applique d’autres opérations au prix (par exemple, appliquer une remise au comptoir), ou queCoffee
soit encore davantage sous-classé.
L’approche avec super()
vous permet de réutiliser le code plutôt que de le copier, et assure le regroupement des fonctionnalités de façon logique – soit deux des plus grands avantages de la programmation orientée objet !
Finissons sur nos films : notre film en cassette ne rentre pas dans le lecteur DVD du salon… 🤔 Peut-être qu’avec la surcharge, nous pouvons proposer une vérification du lecteur (avant de casser le lecteur DVD !) :
À vous de jouer : utilisez la surcharge
Dans cet exercice, nous allons ajouter de la surcharge au code que nous avons utilisé au chapitre précédent.
Mais tout d’abord, voyez-vous des classes dans votre hiérarchie qui devraient être abstraites ? Si oui, transformez-les en classes abstraites.
Surchargez la méthode d’affichage de FilePost
(ou de votre équivalent) pour afficher son fichier ( File
) correspondant en haut du post. Puis, surchargez la méthode d’affichage de votre classe Image
pour écrire dans la sortie standard le nom de l’image.
En résumé
Une classe enfant peut fournir sa propre implémentation d’un élément hérité de sa classe parent.
L’implémentation de la classe enfant est prioritaire sur celle du parent – elle surcharge l’implémentation de la classe parent.
On peut utiliser la méthode super pour accéder à des méthodes dans la classe parent que nous avons surchargée.
Une classe abstraite est une classe qui ne peut pas être instanciée – à la place, il faut en hériter.
Dans le chapitre suivant, nous nous pencherons sur différentes façons d’utiliser l’héritage : les hiérarchies d’héritage et l’héritage multiple.