CodeGym /Cours /Python SELF FR /Polymorphisme

Polymorphisme

Python SELF FR
Niveau 16, Leçon 2
Disponible

8.1 Polymorphisme

Le polymorphisme est l'une des principales conceptions de la programmation orientée objet (POO), qui permet aux objets de différentes classes d'utiliser la même interface.

En Python, le polymorphisme est réalisé à travers le typage dynamique et l'héritage. Un aspect important du polymorphisme est la surcharge de méthodes et la substitution de méthodes de la classe de base par des méthodes de la classe dérivée.

Concepts clés du polymorphisme :

Une interface unique pour des objets différents :

Le polymorphisme permet l'utilisation d'une interface unique pour des objets de différentes classes, qui peuvent avoir des implémentations de méthodes différentes.

Typage dynamique :

En Python, le type de variable est déterminé au moment de l'exécution, ce qui permet à la fonction de travailler avec des objets de n'importe quelle classe, tant qu'ils supportent l'interface requise.

Héritage :

Permet de créer des hiérarchies de classes où les sous-classes héritent des propriétés et méthodes de la classe de base, mais peuvent les redéfinir pour leur propre fonctionnalité spécifique.

Exemples de polymorphisme :

Un exemple simple de polymorphisme : les trois classes ont une méthode du même nom move(). Cela signifie que nous pouvons écrire du code qui fonctionnera avec ces objets en même temps.


class Car:
    def move(self):
        pass
        
class Human:
    def move(self):
        pass
        
class Bird:
    def move(self):
        print("Cui-cui!")
        
car = Car()
human = Human()
bird = Bird()
        
for it in [car, human, bird]:
    it.move()

Dans ce cas, « l'interface commune » est le nom de la méthode, ou sa signature si la méthode a des paramètres.

8.2 Redéfinition de méthodes

Le polymorphisme est souvent utilisé avec l'héritage pour créer des hiérarchies de classes où la classe de base définit une interface commune, et les sous-classes implémentent des détails spécifiques.


class Employee:
    def get_salary(self):
        return 1000
        
class FullTimeEmployee(Employee):
    def get_salary(self):
        return 5000
        
class PartTimeEmployee(Employee):
    def get_salary(self):
        return 3000
        
class Intern(Employee):
    pass
        
def print_salary(employee):
    print(employee.get_salary())
        
employees = [FullTimeEmployee(), PartTimeEmployee(), Intern()]
        
for employee in employees:
    print_salary(employee)

Cet exemple est similaire au précédent, mais avec une différence importante - nos classes ne sont pas obligées d'avoir la méthode get_salary, car elle existe toujours dans la classe de base. Maintenant, « l'interface commune » de toutes les classes n'est pas seulement la méthode get_salary(), mais bien la classe Employee avec toutes ses méthodes et attributs.

8.3 Appel de méthodes de classe dérivée

Regardez attentivement le code ci-dessous :

Nous appelons la méthode print_salary(), qui n'existe que dans la classe de base Employee, et elle, à son tour, appelle une autre méthode de la classe de base - get_salary(). Quelles sont donc les salaires qui seront affichés à l'écran ?


class Employee:
    def print_salary(self):
        salary = self.get_salary()
        print(salary)
        
    def get_salary(self):
        return 1000
        
class FullTimeEmployee(Employee):
    def get_salary(self):
        return 5000
        
class PartTimeEmployee(Employee):
    def get_salary(self):
        return 3000
        
class Intern(Employee):
    pass
        
employees = [FullTimeEmployee(), PartTimeEmployee(), Intern()]
        
for employee in employees:
    employee.print_salary()

Important ! Lisez ce qui est écrit ci-dessous - c'est important.

Si nous appelons la méthode print_salary(), par exemple, de la classe FullTimeEmployee, alors la méthode de la classe de base sera appelée, car cette méthode n'est pas déclarée dans la classe elle-même.

Mais cette méthode print_salary() appellera la méthode get_salary() de l'objet self, qui a le type FullTimeEmployee, et non Employee. Donc, ce sera la méthode get_salary() de la classe FullTimeEmployee qui sera appelée !

De plus, la classe FullTimeEmployee peut appeler la méthode get_salary() de la classe de base pour ses propres besoins. Par exemple, nous voulons calculer le salaire en pourcentage du taux de base :


class FullTimeEmployee(Employee):
    def get_salary(self):
        base_salary = super().get_salary()
        return base_salary * 5  
      
  
      
  
      
  
# 500%
class PartTimeEmployee(Employee): def get_salary(self): base_salary = super().get_salary() return base_salary * 3 # 300%

8.4 Surcharge de méthodes

La surcharge de méthodes (method overloading) en Python est la capacité de créer plusieurs méthodes avec le même nom, mais avec des paramètres différents. Cependant, en forme pure, la surcharge de méthodes n'est pas supportée en Python, comme c'est le cas dans d'autres langages (par exemple, C++ ou Java).

En Python, on peut imiter la surcharge de méthodes en utilisant des arguments par défaut, *args et **kwargs.

Exemples de surcharge de méthodes

Nous pouvons implémenter une fonction qui aura un comportement différent en fonction du nombre d'arguments passés. Cela peut être fait de différentes manières, comme ceci :


class Example:
    def display(self, a=None, b=None):
        if a is not None and b is not None: print(a, b)
        elif a is not None: print(a)
        else: print("Pas d'arguments")
        

obj = Example()
obj.display(1, 2)  # Output: 1 2
obj.display(1)  # Output: 1
obj.display()  # Output: Pas d'arguments

On peut aussi prendre en compte le type de données passé - il suffit de faire une vérification du type :


class Example:
    def mod(self, a, b):
        if type(a) == int and type(b) == int: print(a % b)
        elif type(a) == float or type(b) == float: print(round(a / b))
        else: print("Instruction d'aide : a et b doivent être int ou float")
        

obj = Example()
obj.mod(5, 2)  # Output: 1
obj.mod(5.0, 2)  # Output: 2
obj.mod("5", 2)  # Output: Instruction d'aide : a et b doivent être int ou float

Si des types de données incorrects sont transmis, on peut afficher une instruction ou même un lien vers la documentation en ligne - c'est aussi une solution très populaire.

2
Mission
Python SELF FR, niveau 16, leçon 2
Bloqué
Polymorphisme.
Polymorphisme.
2
Mission
Python SELF FR, niveau 16, leçon 2
Bloqué
Monde animal.
Monde animal.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION