edit: Lire la faq un peu plus longtemps j'aime l'idée de l'opérateur << >> surcharger et ajouter comme ami de ces classes, mais je ne sais pas comment cela ne rompt pas l'encapsulation
Comment romprait-elle l'encapsulation?
Vous rompez l'encapsulation lorsque vous autorisez un accès illimité à un membre de données. Considérez les classes suivantes:
class c1 {
public:
int x;
};
class c2 {
public:
int foo();
private:
int x;
};
class c3 {
friend int foo();
private:
int x;
};
c1
n'est évidemment pas encapsulé. Tout le monde peut y lire et le modifier x
. Nous n'avons aucun moyen d'imposer un type de contrôle d'accès.
c2
est évidemment encapsulé. Il n'y a pas d'accès public à x
. Tout ce que vous pouvez faire est d'appeler la foo
fonction, qui effectue une opération significative sur la classe .
c3
? Est-ce moins encapsulé? Permet-il un accès illimité à x
? Permet-il l'accès à des fonctions inconnues?
Non. Il permet précisément à une fonction d'accéder aux membres privés de la classe. Tout comme l'a c2
fait. Et tout comme c2
, la seule fonction qui a accès n'est pas «une fonction inconnue aléatoire», mais «la fonction répertoriée dans la définition de classe». Tout comme c2
, nous pouvons voir, juste en regardant les définitions de classe, une liste complète de qui a accès.
Alors, comment est-ce exactement moins encapsulé? La même quantité de code a accès aux membres privés de la classe. Et tous ceux qui y ont accès sont répertoriés dans la définition de classe.
friend
ne rompt pas l'encapsulation. Cela met certains programmeurs Java mal à l'aise, car lorsqu'ils disent "OOP", ils signifient en fait "Java". Quand ils disent "encapsulation", ils ne signifient pas "les membres privés doivent être protégés contre les accès arbitraires", mais "une classe Java où les seules fonctions capables d'accéder aux membres privés, sont des membres de classe", même si cela n'a aucun sens pour plusieurs raisons .
Premièrement, comme déjà montré, c'est trop restrictif. Il n'y a aucune raison pour que les méthodes amis ne soient pas autorisées à faire de même.
Deuxièmement, ce n'est pas assez restrictif . Considérons une quatrième classe:
class c4 {
public:
int getx();
void setx(int x);
private:
int x;
};
Ceci, selon la mentalité Java précitée, est parfaitement encapsulé.
Et pourtant, cela permet à quiconque de lire et de modifier x . Comment cela a-t-il même un sens? (indice: ce n'est pas le cas)
Conclusion: l'encapsulation consiste à pouvoir contrôler les fonctions pouvant accéder aux membres privés. Il ne s'agit pas précisément de l'emplacement des définitions de ces fonctions.