Aller au contenu

Encapsulation

Définitions

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, on peut 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 :

  • 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

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 Velo
mon_velo = Velo('Pinarello', 'Dogma F', 'Rouge')

# Accès à l'attribut protégé _marque via la méthode get_marque
print(mon_velo.get_marque())  # Pinarello

# Modification de l'attribut protégé _marque via la méthode set_marque
mon_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.

Privé ?

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.

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. 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.