Python: Encapsulation et interface publique d’une Classe

Le mot encapsulation a deux significations différentes, mais liées. Le premier est l’idée d’encapsuler ou de combiner en une seule chose, des données et les méthodes qui opèrent sur ces données. En Python, cela se fait via cours, comme nous l’avons vu.
Le deuxième sens de l’encapsulation met l’accent sur la frontière entre l’intérieur et l’extérieur de la classe, en précisant ce qui est visible pour les utilisateurs d’une classe. Cela signifie souvent partitionner les attributs en public et privé. En Python, il n’existe aucun mécanisme formel pour empêcher l’accès aux attributs d’une classe depuis l’extérieur de cette classe. Donc, en un sens, tout est publique. Cependant, il existe une convention pour préciser ce qui doit être gardé privé. Tout attribut commençant par un trait de soulignement est considéré privé. Pensez-y comme au journal déverrouillé de quelqu’un. Vous pouvez le lire, mais vous ne devrait pas.

class Diary:
def __init__(self, title):
self.title = title
self._entries = []
def addentry(self, entry):
self._entries.append(entry)
def _lastentry(self):
return self._entries[-1]
Python POO

Dans l’exemple ci-dessus, la méthode addentry est publique. N’importe qui peut ajouter une entrée. Cependant, la méthode last entry est privée. On ne devrait pas appeler cette méthode depuis l’extérieur de la classe Diary. (Encore une fois, vous pouvez, mais vous ne devriez pas.) Le titre est également public, mais les entrées de la liste sont privées.

La collection de tous les attributs publics (dans ce cas, addentry et title) constituent l’interface publique de la classe. C’est ce qu’un utilisateur de la classe devrait interagir avec. Par exemple, on peut utiliser la classe ci-dessus comme suit.

mydiary = Diary("Don’t read this!!!")
mydiary.addentry("It was a good day.")
print("The diary is called ", mydiary.title)
The diary is called Don’t read this!!!

L’héritage est une relation 

 L’encapsulation de la classe ne concerne pas la sécurité. 

=> Respecter les attributs privés et s’en tenir à l’interface publique est vraiment pour nous aider à écrire du code fonctionnel qui continuera à fonctionner à l’avenir. Le code se change tout le temps. Si vous modifiez une classe qui est utilisée ailleurs dans le code, vous devez faire attention à ne pas casser ce code. Si l’interface publique et son comportement ne change pas, alors on peut être confiant que les modifications n’affectent pas l’autre code. On pourrait changer le nom d’une variable privée, dites changer les entrées en entrées de journal et soyez confiant que cela ne causera pas la rupture d’un autre code ailleurs.

Chaque fois que nous parlons des types de choses de notre vie quotidienne, il est possible en parler à différents niveaux de généralité. On peut parler d’un joueur de basket spécifique, disons Kyrie Irving, ou nous pouvons parler de professionnel les basketteurs, ou tous les basketteurs, ou les gens, ou les êtres vivants.

Le joueur spécifique avec lequel nous avons commencé pourrait être considéré comme appartenant à l’un de ces classes. Le même principe s’applique au code que nous écrivons.

Considérez cet exemple d’un programme de géométrie.

class Triangle:
def __init__(self, points):
self._sides = 3
self._points = list(points)
if len(self._points) != 3:
raise ValueError("Wrong number of points.")
def sides(self):
return 3
def __str__(self):
return "I’m a triangle."
class Square:
def __init__(self, points):
self._sides = 4
self._points = list(points)
if len(self._points) != 4:
raise ValueError("Wrong number of points.")
def sides(self):
return 4
def __str__(self):
return "I’m so square."

Ce sont évidemment des classes très proches. L’un peut en faire un autre classe dont ces deux classes sont des sous-classes. Ensuite, tout ce qui est commun entre les deux classes peut être mis dans la classe plus grande ou la superclasse.

class Polygon:
def __init__(self, sides, points):
self._sides = sides
self._points = list(points)
if len(self._points) != self._sides:
raise ValueError("Wrong number of points.")
def sides(self):
return self._sides
class Triangle(Polygon):
def __init__(self, points):
Polygon.__init__(self, 3, points)
def __str__(self):
return "I’m a triangle."
class Square(Polygon):
def __init__(self, points):
Polygon.__init__(self, 4, points)
def __str__(self):
return "I’m so square."

Notez que les définitions de classe Triangle et Carré indiquent maintenant la classe Polygone entre parenthèses. C’est ce qu’on appelle l’héritage. La classe Triangle hérite de (ou étend) la classe Polygon. La superclasse Polygon et les sous-classes sont Triangle et Square. Quand nous appelons une méthode sur un objet, si cette méthode n’est pas définie dans la classe de cet objet, Python recherchera la méthode dans la superclasse. Cette recherche pour que la fonction correcte à appeler s’appelle l’ordre de résolution de la méthode. Si une méthode de la superclasse est redéfinie dans la sous-classe, puis en appelant la méthode sur une instance de la sous-classe appelle à la place la méthode de la sous-classe.

L’initialiseur de la superclasse n’est pas appelé automatiquement lorsque nous créons une nouvelle instance (sauf si nous n’avons pas défini init dans la sous-classe). Dans ce cas, nous appelons manuellement le polygone. fonction d’initialisation. C’est l’un des rares fois où il est acceptable d’appeler une méthode dunder par son nom.

Lorsque vous utilisez l’héritage, vous devez toujours vous souvenir de la règle d’héritage la plus importante :

L’héritage signifie a.

Cela signifie que si ClassB étend ClassA, alors un objet ClassB est un Objet de classeA. Cela devrait être vrai au niveau conceptuel. Ainsi, dans notre exemple de formes, nous avons suivi cette règle, car un triangle est un polygone.

Au total, cela pourrait ressembler à plus de code. Cependant, il y a moins de doublons.

La duplication est très mauvaise. Même s’il est facile de copier et coller sur un ordinateur, c’est une source de nombreux bogues. 

Les bogues sont partout. Si vous copiez et collez un code avec un bogue, alors vous avez maintenant deux bogues. Si vous trouvez le bogue, vous devez espérer que vous vous souviendrez de corriger les deux endroits. Chaque fois que vous comptez sur votre mémoire, vous obtiendrez vous-même en difficulté.

Autres articles

Héritage en Python : Comprendre les Fondements...
L'héritage est l'un des concepts fondamentaux de la programmation orientée...
Read more
Guide Complet sur les Nombres Premiers en...
Dans cet article, nous explorerons en détail ce...
Read more
Vérifier si une chaîne de caractères est...
Cet article explore différentes approches pour vérifier si une chaîne...
Read more

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *