Encapsulation
Définition : Encapsulation
L’encapsulation est un concept clé en POO qui permet de cacher les détails d’implémentation d’un objet et de contrôler l’accès à ses attributs et méthodes. En utilisant l’encapsulation, nous pouvons protéger les données d’un objet et garantir que son état reste valide.
En Python, l’encapsulation est réalisée en utilisant des conventions de nommage pour les attributs et les méthodes. Par exemple, un attribut ou une méthode dont le nom commence par un seul underscore (_) est considéré comme protégé et ne doit pas être accédé directement depuis l’extérieur de la classe. Un attribut ou une méthode dont le nom commence par deux underscores (__) est considéré comme privé et ne peut pas être accédé directement depuis l’extérieur de la classe.
Exemple : Velo
class Velo:
"""Représente un vélo avec une marque, un modèle et une couleur."""def __init__(self, marque, modele, couleur):
"""Initialise les attributs du vélo avec les valeurs données."""self._marque = marque
self._modele = modele
self._couleur = couleur
def get_marque(self):
"""Retourne la marque du vélo."""return self._marque
def set_marque(self, nouvelle_marque):
"""Modifie la marque du vélo."""if nouvelle_marque == '':
raise ValueError("La marque ne peut pas être vide.")
self._marque = nouvelle_marque
# Création d'un objet Velomon_velo = Velo('Peugeot', 'E01 D9', 'bleu')
# Accès à l'attribut protégé _marque via la méthode get_marqueprint(mon_velo.get_marque()) # Peugeot
# Modification de l'attribut protégé _marque via la méthode set_marquemon_velo.set_marque('Bianchi')
print(mon_velo.get_marque()) # Bianchi
# Tentative d'accès direct à l'attribut protégé _marque (déconseillé)print(mon_velo._marque) # Bianchi
Dans cet exemple, nous avons défini une classe Velo avec des attributs protégés _marque, _modele et _couleur. Ces attributs sont initialisés dans la méthode __init__ et ne doivent pas être accédés directement depuis l’extérieur de la classe.
Nous avons également défini des méthodes get_marque et set_marque pour accéder et modifier l’attribut _marque de manière contrôlée. La méthode get_marque retourne simplement la valeur de l’attribut _marque, tandis que la méthode set_marque vérifie que la nouvelle valeur est valide avant de modifier l’attribut.
Ensuite, nous avons créé un objet mon_velo à partir de la classe Velo et avons utilisé les méthodes get_marque et set_marque pour accéder et modifier l’attribut _marque de manière contrôlée. Comme on peut le voir, ces méthodes nous permettent de protéger les données de l’objet et de garantir que son état reste valide.
Attention : Il ne faut jamais accéder ou modifier un attribut protégé ou privé
En programmation orientée objet, il est déconseillé d'accéder ou de modifier directement un attribut protégé ou privé pour plusieurs raisons :
1. Encapsulation : L'un des principes fondamentaux de la programmation orientée objet est l'encapsulation, qui consiste à cacher les détails d'implémentation d'un objet et à contrôler l'accès à ses attributs et méthodes. En accédant ou en modifiant directement un attribut protégé ou privé, on viole ce principe d'encapsulation.
2. Intégrité des données : Les attributs protégés ou privés sont souvent utilisés pour stocker des données qui doivent rester cohérentes. Si ces attributs sont modifiés directement, cela peut entraîner un état incohérent de l'objet.
3. Maintenance du code : Si un attribut protégé ou privé est accédé ou modifié directement à plusieurs endroits dans le code, cela peut rendre le code plus difficile à maintenir. Si la façon dont l'attribut est utilisé doit être modifiée, tous les endroits où l'attribut est accédé ou modifié doivent être trouvés et modifiés.
Pour ces raisons, il est préférable d'accéder et de modifier les attributs protégés et privés par le biais de méthodes publiques, souvent appelées getters et setters. Ces méthodes permettent de contrôler l'accès aux attributs protégés et privés et peuvent inclure des vérifications pour garantir que les nouvelles valeurs sont valides.
Complément : Pour aller plus loin ...
En Python, il est techniquement possible d’accéder à un attribut privé depuis l’extérieur de la classe, mais cela est généralement considéré comme une mauvaise pratique. Un attribut privé est un attribut qui commence par deux underscores (__) et qui est destiné à être utilisé uniquement à l’intérieur de la classe où il est défini.
Python utilise un mécanisme appelé “name mangling” pour empêcher l’accès direct aux attributs privés depuis l’extérieur de la classe. Lorsqu'on définit un attribut privé, son nom est modifié en ajoutant un préfixe _NomDeLaClasse devant son nom. Par exemple, si on définit un attribut privé __attribut dans une classe MaClasse, son nom sera modifié en _MaClasse__attribut.
Cependant, il est toujours possible d’accéder à cet attribut en utilisant son nom modifié. Par exemple, si on a un objet mon_objet de la classe MaClasse, on peut accéder à son attribut privé __attribut en utilisant la syntaxe suivante :
valeur = mon_objet._MaClasse__attribut
Bien que cela soit possible, il est fortement déconseillé d’accéder directement aux attributs privés de cette manière. Les attributs privés sont destinés à être utilisés uniquement à l’intérieur de la classe et leur accès direct peut entraîner des comportements imprévus et des erreurs difficiles à déboguer. Au lieu de cela, on doit utiliser des méthodes publiques pour accéder et modifier les attributs privés de manière contrôlée.