Héritage

Python SELF FR
Niveau 15 , Leçon 6
Disponible

6.1 L'héritage - c'est simple

L'héritage est un concept fondamental de la programmation orientée objet (OOP) qui permet à une classe (appelée classe fille ou sous-classe) d'hériter des champs et des méthodes d'une autre classe (appelée la classe parente ou super-classe).

Cette approche permet de créer des classes plus générales et de réutiliser le code, améliorant ainsi l'organisation et la maintenabilité du code.

Pourquoi a-t-on besoin de l'héritage ?

Supposons que tu as besoin d'écrire un code et que tu as décidé de le faire sous forme de classe. Puis tu découvres qu'il y a déjà une classe dans ton projet qui fait presque tout ce qu'il te faut. Tu peux simplement copier ce code dans ta classe et l'utiliser à ta guise.

Ou, tu peux "comme copier". Tu peux déclarer cette classe comme parent de la tienne, et Python ajoutera à ta classe le comportement du parent.

Imagine que tu es la nature et que tu veux créer un chien. Qu'est-ce qui serait plus rapide: créer un chien à partir d'une bactérie en un milliard d'années ou domestiquer un loup en 200 000 ans ?

Exemple d'héritage basique

Supposons que tu as une classe parente Animal avec un champ name :


class Animal:
    def __init__(self, name):
        self.name = name

Nous voulons créer deux classes filles pour cela — Dog et Cat, et leur ajouter à toutes deux la méthode speak :


class Dog(Animal):
    def speak(self):
        return f"{self.name} dit Woof!"

class Cat(Animal):
    def speak(self):
        return f"{self.name} dit Meow!"

Dans l'exemple ci-dessus, les classes filles Dog et Cat héritent de Animal et ajoutent la méthode speak.

Classe Dog :

  • Hérite de l'attribut name de Animal.
  • Ajoute une méthode speak qui retourne une chaîne spécifique aux chiens.

Classe Cat :

  • Hérite de l'attribut name de Animal.
  • Ajoute une méthode speak qui retourne une chaîne spécifique aux chats.

La version finale du code ressemble à ceci :


class Animal:
    def __init__(self, name):
        self.name = name
         
class Dog(Animal):
    def speak(self):
        return f"{self.name} dit Woof!"
        
class Cat(Animal):
    def speak(self):
        return f"{self.name} dit Meow!"
         
dog = Dog("Buddy")
cat = Cat("Whiskers")
        
print(dog.speak())  # Affiche: Buddy dit Woof!
print(cat.speak())  # Affiche: Whiskers dit Meow!

Dans cet exemple, Animal est la classe parente, et Dog et Cat sont les classes filles. Les classes filles héritent de l'attribut name et de la méthode __init__ de la classe parente Animal, mais ajoutent les méthodes speak.

6.2 Sous le capot de l'héritage

Si tu as ajouté un parent à ta classe, alors c'est très similaire à comme si tu avais copié le code du parent dans ta classe.


class Animal:
    def __init__(self, name):
        self.name = name
         

class Dog(Animal):
    def __init__(self, name):
        super().__init__(name)  # Appel du constructeur de la classe parente
        
    def speak(self):
        return f"{self.name} dit Woof!"
        
class Cat(Animal):
    def __init__(self, name):
        super().__init__(name)  # Appel du constructeur de la classe parente
        
    def speak(self):
        return f"{self.name} dit Meow!"
        

dog = Dog("Buddy")
cat = Cat("Whiskers")
        
print(dog.speak())  # Affiche: Buddy dit Woof!
print(cat.speak())  # Affiche: Whiskers dit Meow!

Ce n'est pas tout à fait exact, mais si tu n'as jamais rencontré le concept d'héritage, tu peux pour l'instant y penser de cette façon. Nous ajouterons plus de détails par la suite.

6.3 Hiérarchie d'héritage

Très souvent, lorsque tu conçois un modèle complexe avec un grand nombre de classes, tu peux rencontrer une hiérarchie complète d'héritage.

Par exemple, tu as une classe Animal — c'est la classe de base pour tous les animaux :


class Animal:
    def __init__(self, name):
        self.name = name
        
    def speak(self):
        raise NotImplementedError("Subclass must implement abstract method")

Nous avons même ajouté une méthode speak, mais comme un animal abstrait ne parle pas, cette méthode lance simplement l'exception NotImplementedError — c'est une pratique standard.

Ensuite, nous ajoutons des classes intermédiaires qui correspondent aux catégories d'animaux: Mammal pour les mammifères et Bird pour les oiseaux.


class Mammal(Animal):
    def __init__(self, name, fur_color):
        super().__init__(name)  # Appel du constructeur de la classe parente
        self.fur_color = fur_color
         

class Bird(Animal):
    def __init__(self, name, wing_span):
        super().__init__(name)  # Appel du constructeur de la classe parente
        self.wing_span = wing_span
        
    def fly(self):
        return f"{self.name} vole avec une envergure de {self.wing_span} mètres."

Et enfin, seulement à la toute dernière étape apparaissent les classes des espèces animales spécifiques :


class Dog(Mammal):
    def speak(self):
        return f"{self.name} dit Woof!"
         
        
class Cat(Mammal):
    def speak(self):
        return f"{self.name} dit Meow!"
        
class Parrot(Bird):
    def speak(self):
        return f"{self.name} dit Squawk!"

C'est avec eux que le code final fonctionne généralement :


animals = [Dog("Buddy", "brown"), Cat("Whiskers", "white"), Parrot("Polly", 0.5)]
            
for animal in animals:
    print(animal.speak())

print(f"{dog.name} a un pelage {dog.fur_color}.")  # Affiche: Buddy a un pelage marron.
print(f"{cat.name} a un pelage {cat.fur_color}.")  # Affiche: Whiskers a un pelage blanc.
print(parrot.fly())  # Affiche: Polly vole avec une envergure de 0.5 mètres.

Bien qu'il n'y ait techniquement pas de restrictions sur la création de hiérarchies avec des dizaines d'ancêtres, il est important de se rappeler que sans nécessité, il vaut mieux rester simple. La force réside dans la simplicité.

1
Опрос
Classes et POO,  15 уровень,  6 лекция
недоступен
Classes et POO
Classes et POO
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION