Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Héritage et polymorphisme en Python

Après cette leçon: Je peux réutiliser du code par héritage et faire appeler la même méthode sur des objets de classes différentes.

Leçon de 55 min6 commandesLab Linux du quotidien : la trentaine de commandes que les ingénieurs tapent de tête

Qu’est-ce que l’héritage en programmation objet ?

L’héritage permet à une classe de reprendre les attributs et les méthodes d’une autre classe, puis d’y ajouter ou d’en changer. Il évite de recopier le même code dans plusieurs classes qui se ressemblent.

Un service de livraison envoie des colis ordinaires, express et fragiles. Tous ont un poids et un coût, mais le coût ne se calcule pas de la même façon.

À la fin de cette leçon

Remarque

Je peux réutiliser du code par héritage et faire appeler la même méthode sur des objets de classes différentes.

Mots-clés

MotCe que ça veut direExemple
Héritagele fait qu’une classe reprenne ce que fait une autre classe
Classe mèrela classe dont on hériteclass Colis:
Classe fillela classe qui hériteclass ColisExpress(Colis):
Redéfinitionune méthode de la fille qui remplace celle de la mère
super()l’appel de la méthode de la classe mère
Polymorphismele même appel qui fait des choses différentes selon l’objet

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Recopier une classe est le chemin des fautes

Un colis ordinaire coûte 500 centimes plus 100 par kilo. Un colis express coûte la même chose plus 1 000.

Si vous recopiez la classe Colis pour écrire ColisExpress, le jour où le tarif de base change, il faut penser à corriger les deux. On en oublie toujours une.

Une classe fille hérite de sa mère

Code: python
class Colis:
    def __init__(self, poids_kg):
        self.poids_kg = poids_kg

    def cout(self):
        return 500 + 100 * self.poids_kg


class ColisExpress(Colis):
    pass


colis = ColisExpress(2)
print(colis.poids_kg, colis.cout())

Une fille redéfinit une méthode et appelle super()

ColisExpress(Colis) reprend tout de Colis, sans rien recopier. Pour changer le coût, la fille écrit une méthode du même nom : c’est la redéfinition.

Dans cette méthode, super().cout() appelle la méthode de la mère. La fille ajoute son supplément au coût de base.

Ajouter le supplément express avec super

Code: python
class Colis:
    def __init__(self, poids_kg):
        self.poids_kg = poids_kg

    def cout(self):
        return 500 + 100 * self.poids_kg


class ColisExpress(Colis):
    def cout(self):
        return super().cout() + 1000


print(Colis(2).cout(), ColisExpress(2).cout())

Créer un dossier pour les essais

Commande
mkdir -p essais

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire la famille de colis

Commande
printf 'class Colis:\n    def __init__(self, poids_kg):\n        self.poids_kg = poids_kg\n\n    def cout(self):\n        return 500 + 100 * self.poids_kg\n\n\nclass ColisExpress(Colis):\n    def cout(self):\n        return super().cout() + 1000\n\n\nclass ColisFragile(Colis):\n    def cout(self):\n        return super().cout() + 300\n' > essais/colis.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Comparer les trois coûts pour 2 kilos

Commande
PYTHONPATH=essais python3 -c "from colis import Colis, ColisExpress, ColisFragile; print(Colis(2).cout(), ColisExpress(2).cout(), ColisFragile(2).cout())"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Le polymorphisme : un appel, plusieurs comportements

Parcourez une liste qui mélange des colis de trois classes. À chaque tour, vous écrivez colis.cout() et vous n’avez pas à vous demander de quelle classe il s’agit.

Chaque objet répond avec sa propre version de la méthode. C’est le polymorphisme. Il supprime les longues suites de if sur le type.

Écrire un programme qui parcourt un lot

Commande
printf 'from colis import Colis, ColisExpress, ColisFragile\n\nlot = [Colis(1), ColisExpress(1), ColisFragile(1)]\nfor colis in lot:\n    print(type(colis).__name__, colis.cout())\n' > essais/lot.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Lancer le programme du lot

Commande
python3 essais/lot.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Une fille est aussi une mère

Commande
PYTHONPATH=essais python3 -c "from colis import Colis, ColisExpress; print(isinstance(ColisExpress(1), Colis), isinstance(Colis(1), ColisExpress))"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Erreur fréquente

Attention

Beaucoup pensent qu’il faut hériter dès que deux classes partagent du code. L’héritage dit « est un » : un colis express est un colis. Si la phrase est fausse, n’héritez pas. Vous verrez à la leçon suivante quoi faire à la place.

Écrire une famille de colis

Dans le devoir, la classe Colis est déjà écrite. Vous écrivez ColisExpress (1 000 centimes en plus) et ColisFragile (300 en plus), en appelant super().

Vous écrivez aussi total_cout(colis), qui additionne le coût d’une liste de colis de classes mêlées.

À propos de ce labo et de sa source: Lab Linux du quotidien : la trentaine de commandes que les ingénieurs tapent de tête

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.