Passer au contenu principal
eLearner.app
Module 7 · Leçon 2 sur 426/36 dans le cours~12 min
Leçons du module (2/4)

Héritage

L'héritage (inheritance) permet de créer une nouvelle classe (la subclass ou sous-classe) qui hérite des attributs et méthodes d'une classe existante (la base class ou classe de base), et peut les étendre ou les remplacer (override).

Syntaxe de base

Python
class Animale:
    def __init__(self, nome):
        self.nome = nome

    def saluta(self):
        return f"{self.nome} fa un verso"

class Cane(Animale):       # Cane HÉRITE de Animale
    def saluta(self):       # OVERRIDE du méthode (redéfinition)
        return f"{self.nome} dice WOOF!"

a = Animale("X")
c = Cane("Fido")
a.saluta()      # 'X fa un verso'
c.saluta()      # 'Fido dice WOOF!'

Cane hérite de __init__ d'Animale sans avoir besoin de le réécrire.

super() : appeler la méthode de base

Lorsque vous souhaitez étendre une méthode de base (et non la remplacer complètement), utilisez super() :

Python
class Animale:
    def __init__(self, nome):
        self.nome = nome

class Cane(Animale):
    def __init__(self, nome, razza):
        super().__init__(nome)    # délègue à la base
        self.razza = razza

c = Cane("Fido", "Labrador")
c.nome        # 'Fido'
c.razza       # 'Labrador'

isinstance : vérification du type

Python
isinstance(c, Cane)        # True
isinstance(c, Animale)     # True (la base aussi)
isinstance(c, str)         # False

isinstance(x, BaseClass) reconnaît également toutes les sous-classes : c'est ce qui rend l'héritage utile pour le polymorphisme.

Python
animali = [Cane("Fido", "X"), Animale("Pippo")]
for a in animali:
    print(a.saluta())        # chaque objet répond à sa manière

MRO (Method Resolution Order) — aperçu

En cas d'héritage multiple, Python décide dans quel ordre chercher une méthode en suivant le MRO, calculé avec l'algorithme C3. Dans 95 % des cas, il suffit de savoir :

  1. il cherche d'abord dans l'instance,
  2. puis dans sa classe,
  3. puis dans les classes de base dans l'ordre de leur déclaration.
Python
Cane.__mro__
# (<class 'Cane'>, <class 'Animale'>, <class 'object'>)

object est la racine de toutes les classes en Python 3.

À vous de jouer

Exercice#python.m7.l2.e1
Tentatives : 0Chargement…

Étant donné `class Vehicle: def __init__(self, brand): self.brand = brand`, définissez `Car(Vehicle)` avec __init__(self, brand, model) qui appelle super().__init__ et stocke self.model. Créez `a = Car('Fiat', '500')` et évaluez `(a.brand, a.model)`.

Chargement de l'éditeur…
Afficher l'indice

super().__init__(brand) puis self.model = model.

Solution disponible après 3 tentatives

Exercice de révision

Exercice#python.m7.l2.e2
Tentatives : 0Chargement…

Définissez `class Shape: def area(self): return 0` et `class Square(Shape)` avec __init__(self, side) et area() qui renvoie side * side. Créez `q = Square(5)` et évaluez le tuple `(q.area(), isinstance(q, Shape))`.

Chargement de l'éditeur…
Afficher l'indice

self.side * self.side.

Solution disponible après 3 tentatives

Défi supplémentaire

Exercice#python.m7.l2.e3
Tentatives : 0Chargement…

Créez une classe `Square` qui hérite de la classe `Rectangle` (définie ci-dessous). Le constructeur de `Square` doit prendre un paramètre unique `side` et le passer à `super().__init__(side, side)`. Instanciez un carré avec un côté de `6` dans `sq` et évaluez `sq.area()`.

Chargement de l'éditeur…
Afficher l'indice

Déclarez class Square(Rectangle): et appelez super().__init__(side, side) dans le constructeur.

Solution disponible après 3 tentatives