Python - Héritage

Qu'est-ce qu'Héritage en Python ?

L'héritage est un concept fondamental de la programmation orientée objet (POO) qui permet à une classe d'hériter des propriétés et des méthodes d'une autre classe. Cela permet de réutiliser et de modulariser le code, car vous pouvez créer de nouvelles classes basées sur des classes existantes sans avoir à réécrire le même code. En Python, l'héritage est implémenté en utilisant le mot-clé class suivi du nom de la classe parente entre parenthèses.

Python - Inheritance

Création d'une Classe Parent

Commençons par créer une simple classe parent appelée Animal :

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

def speak(self):
raise NotImplementedError("La sous-classe doit implémenter cette méthode")

Dans cet exemple, nous définissons une classe Animal avec une méthode __init__ qui initialise l'attribut name et une méthode speak qui lève une NotImplementedError. Cette erreur sera levée si la sous-classe ne fournit pas sa propre implémentation de la méthode speak.

Création d'une Classe Enfant

Maintenant, créons une classe enfant appelée Dog qui hérite de la classe Animal :

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

La classe Dog hérite de toutes les attributs et méthodes de la classe Animal, mais elle fournit sa propre implémentation de la méthode speak. Lorsque nous créons une instance de la classe Dog et appelons sa méthode speak, elle retournera "[nom du chien] dit Woof !" au lieu de lever une erreur.

mon_chien = Dog("Buddy")
print(mon_chien.speak())  # Sortie : Buddy dit Woof !

Types d'Héritage

Il y a trois types d'héritage en Python : héritage simple, héritage multiple, héritage multinationnel et héritage hiérarchique. Nous allons explorer chaque type en détail.

Python - Héritage Simple

L'héritage simple est la forme la plus courante d'héritage, où une classe hérite d'une seule classe parent. Comme nous l'avons vu ci-dessus, la classe Dog hérite de la classe Animal, ce qui est un exemple d'héritage simple.

Python - Héritage Multiple

L'héritage multiple se produit lorsqu'une classe hérite de plus d'une classe parent. Cependant, Python ne supporte pas directement l'héritage multiple par le biais de la syntaxe de définition de classe. Au lieu de cela, il utilise une technique appelée "mixins" ou "interfaces" pour réaliser l'héritage multiple.

Ordre de Résolution des Méthodes (MRO)

Python utilise l'algorithme de linéarisation C3 pour déterminer l'ordre dans lequel les classes de base sont recherchées lors de la recherche d'une méthode. La MRO garantit que chaque classe apparaît au plus une fois dans l'ordre de résolution des méthodes et maintient l'ordre des classes de base tel qu'il a été spécifié dans la définition de classe.

Python - Héritage Multinationnel

L'héritage multinationnel se produit lorsqu'une classe hérite d'une sous-classe, formant une hiérarchie de classes. Voici un exemple :

class Mammifère(Animal):
pass

class Chat(Mammifère):
def speak(self):
return f"{self.name} dit Miaou !"

Dans ce cas, la classe Chat hérite de la classe Mammifère, qui hérite à son tour de la classe Animal. Cela forme une hiérarchie d'héritage multinationnel.

Python - Héritage Hiérarchique

L'héritage hiérarchique implique plusieurs sous-classes héritant d'une seule superclasse. Par exemple :

class Reptile(Animal):
pass

class Serpent(Reptile):
def speak(self):
return f"{self.name} dit Sss !"

class Lézard(Reptile):
def speak(self):
return f"{self.name} dit Rampe !"

Dans ce cas, les classes Serpent et Lézard héritent toutes deux de la classe Reptile, qui hérite à son tour de la classe Animal. Cela forme une structure d'héritage hiérarchique.

Python - Héritage Hybride

L'héritage hybride combine les fonctionnalités de l'héritage multiple et d'autres types d'héritage. Il n'est pas directement supporté en Python, mais peut être réalisé en utilisant des mixins ou en combinant différents types d'héritage.

La fonction super()

La fonction super() est utilisée pour appeler des méthodes de la classe parente à l'intérieur de la sous-classe. Elle est particulièrement utile lorsque vous souhaitez étendre ou remplacer une méthode de la classe parente tout en conservant une partie de sa fonctionnalité. Voici un exemple :

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

def speak(self):
return f"{self.name} dit Chirp !"

Dans ce cas, la classe Oiseau hérite de la classe Animal et utilise la fonction super() pour appeler la méthode __init__ de la classe parente. Cela garantit que l'attribut name est correctement initialisé. De plus, la classe Oiseau fournit sa propre implémentation de la méthode speak.

mon_oiseau = Oiseau("Tweety", 10)
print(mon_oiseau.speak())  # Sortie : Tweety dit Chirp !

En utilisant l'héritage, vous pouvez créer des classes plus spécialisées qui héritent et étendent la fonctionnalité de leurs classes parentes, en promouvant la réutilisabilité et l'organisation du code. N'oubliez pas que l'héritage n'est qu'un aspect de la POO, et que des concepts tels que le polymorphisme, l'encapsulation et l'abstraction jouent également un rôle crucial dans la conception de systèmes logiciels robustes et maintenables.

Credits: Image by storyset