Polymorphisme et Comportement Polymorphe
I. Polymorphisme
Le polymorphisme désigne le fait qu'une entité peut prendre plusieurs formes. Un concept abstrait peut avoir plusieurs implémentations concrètes, ce qui signifie que le polymorphisme dépend de l'héritage
1.1 Les animaux peuvent avoir plusieurs formes : humains, chiens, porcs
python3 :
#!/usr/bin/env python
#coding:utf8
import abc
class EtreVivant(metaclass=abc.ABCMeta): # Concept abstrait : être vivant
@abc.abstractmethod
def communiquer(self):
pass
class Humain(EtreVivant): # Une forme d'être vivant : humain
def communiquer(self):
print('dire bonjour')
class Chien(EtreVivant): # Une autre forme d'être vivant : chien
def communiquer(self):
print('aboyer')
class Cochon(EtreVivant): # Une troisième forme d'être vivant : cochon
def communiquer(self):
print('grognement')
h = Humain()
c = Chien()
p = Cochon()
# h, c, p sont tous des êtres vivants, tout être vivant doit avoir une méthode communiquer
# Ainsi, nous pouvons utiliser directement ces méthodes sans nous soucier de leurs types spécifiques
h.communiquer()
c.communiquer()
p.communiquer()
1.2 Les fichiers peuvent avoir plusieurs formes : fichier texte, fichier exécutable
import abc
class Document(metaclass=abc.ABCMeta): #Concept abstrait : document
@abc.abstractmethod
def executer(self):
pass
class Texte(Document): #Une forme de document : fichier texte
def executer(self):
print('ouvrir document')
class Executable(Document): #Une autre forme de document : fichier exécutable
def executer(self):
print('lancer document')
II. Comportement Polymorphe
Note : Le polymorphisme et le comportement polymorphe sont deux concepts distincts
Qu'est-ce que le polymorphisme dynamique (lorsqu'il est utilisé dans un contexte d'héritage, parfois appelé aussi comportement polymorphe)
1.1 Le comportement polymorphe consiste à utiliser des instances sans considérer leur type spécifique
En utilisant des instances sans considérer leur type, on peut apppeler les mêmes méthodes sur des objets de types différents. Par exemple, humains, chats, chiens, etc., tant qu'ils héritent d'EtreVivant, on peut directement appeler leur méthode communiquer().
Exemple 1 : python3
#!/usr/bin/env python
#coding:utf8
import abc
class EtreVivant(metaclass=abc.ABCMeta): # Concept abstrait : être vivant
@abc.abstractmethod
def communiquer(self):
pass
class Humain(EtreVivant): # Une forme d'être vivant : humain
def communiquer(self):
print('dire bonjour')
class Chien(EtreVivant): # Une autre forme d'être vivant : chien
def communiquer(self):
print('aboyer')
class Cochon(EtreVivant): # Une troisième forme d'être vivant : cochon
def communiquer(self):
print('grognement')
h = Humain()
c = Chien()
p = Cochon()
# h, c, p sont tous des êtres vivants, tout être vivant doit avoir une méthode communiquer
# Ainsi, nous pouvons utiliser directement ces méthodes sans nous soucier de leurs types spécifiques
h.communiquer()
c.communiquer()
p.communiquer()
Pourquoi utiliser le comportement polymorphe (avantages du polymorphisme)
Comme on peut le voir dans l'exemple précédent, nous n'avons ajouté aucune nouvelle connaissance, ce qui signifie que Python lui-même supporte le polymorphisme. Quels sont les avantages de cette approche ?
1.1 Augmentation de la flexibilité du programme
Avec une approche constante pour faire face aux changements, peu importe comment les objets varient, l'utilisateur les de la même manière, comme dans fonction(etre_vivant)
1.2 Augmentation de l'extensibilité du programme
En créant une nouvelle classe qui hérite de la classe EtreVivant, l'utilisateur n'a pas besoin de modifier son propre code, il continue d'utiliser fonction(etre_vivant)
#!/usr/bin/env python
#coding:utf8
import abc
class EtreVivant(metaclass=abc.ABCMeta): # Concept abstrait : être vivant
@abc.abstractmethod
def communiquer(self):
pass
class Humain(EtreVivant): # Une forme d'être vivant : humain
def communiquer(self):
print('dire bonjour')
class Chien(EtreVivant): # Une autre forme d'être vivant : chien
def communiquer(self):
print('aboyer')
class Cochon(EtreVivant): # Une troisième forme d'être vivant : cochon
def communiquer(self):
print('grognement')
class Chat(EtreVivant): # Une autre forme d'être vivant : chat
def communiquer(self):
print('miauler')
def fonction(etre_vivant): # Pour l'utilisateur, son code n'a pas besoin d'être modifié
etre_vivant.communiquer()
h = Humain()
c = Chien()
p = Cochon()
# h, c, p sont tous des êtres vivants, tout être vivant doit avoir une méthode communiquer
# Ainsi, nous pouvons utiliser directement ces méthodes sans nous soucier de leurs types spécifiques
h.communiquer()
c.communiquer()
p.communiquer()
chat1 = Chat() # Création d'une instance de chat
fonction(chat1) # L'appel reste identique pour utiliser la fonctionnalité communiquer du chat
'''Ainsi, en ajoutant une nouvelle forme Chat, l'utilisateur peut utiliser la nouvelle classe sans modifier son propre code.'''
III. Typage Canard
Moment amusant :
Python favorise le typage canard, c'est-à-dire 'si ça ressemble à un canard, ça cancane comme un canard et ça marche comme un canard, alors c'est un canard'
Les programmeurs Python utilisent souvent ce comportement pour écrire leurs programmes. Par exemple, si vous voulez créer une version personnalisée d'un objet existant, vous pouvez hériter de cet objet
ou créer un objet entièrement nouveau qui a l'apparence et le comportement d'un canard, mais sans aucun lien avec lui. Cette approche est généralement utilisée pour maintenir un faible couplage entre les composants du programme.
Exemple 1 : Utilisation des divers objets 'similaires à un fichier' définis dans la bibliothèque standard, bien que ces objets fonctionnent comme des fichiers, ils n'héritent pas des méthodes des objets de fichier intégrés
#Les deux classes ressemblent à des canards, les deux semblent être des fichiers, donc elles peuvent être utilisées comme des fichiers
class FichierTexte:
def lire(self):
pass
def ecrire(self):
pass
class FichierDisque:
def lire(self):
pass
def ecrire(self):
pass
Exemple 2 : En réalité, vous profitez constamment des avantages du polymorphisme, par exemple, les types de séquence en Python ont plusieurs formes : chaînes de caractères, listes, tuples, le polymorphisme se manifeste comme suit
#str, list, tuple sont tous des types de séquence
s=str('bonjour')
l=list([1,2,3])
t=tuple((4,5,6))
#Nous pouvons utiliser s, l, t sans considérer leurs types spécifiques
s.__len__()
l.__len__()
t.__len__()
len(s)
len(l)
len(t)