Pourquoi avons-nous besoin de variables privées?


210

Pourquoi avons-nous besoin de variables privées dans les classes?

Tous les livres sur la programmation que j'ai lus disent qu'il s'agit d'une variable privée, c'est comment vous le définissez mais vous vous arrêtez là.

Le libellé de ces explications m'a toujours semblé comme une crise de confiance dans notre métier. Les explications semblaient toujours comme si d’autres programmeurs cherchaient à perturber notre code. Pourtant, de nombreux langages de programmation ne comportent pas de variables privées.

  1. Qu'est-ce que les variables privées aident à prévenir?

  2. Comment décidez-vous si une propriété particulière doit être privée ou non? Si par défaut chaque champ DEVRAIT être privé, alors pourquoi y a-t-il des données membres dans une classe?

  3. Dans quelles circonstances une variable devrait-elle être rendue publique?


9
Votre question semble très agnostique au regard de la langue, mais vous l'avez étiquetée en tant que java et c ++. Si vous êtes intéressé par des points de vue extérieurs à ces deux langues, vous devriez probablement le dire.
James

8
Pour mémoire, créer une méthode privée n'augmente pas la "sécurité". D'autres parties de votre application peuvent toujours accéder aux membres privés à l'aide de la réflexion.
kba

3
L'utilisation et la différence des variables privées et publiques, et la raison pour laquelle nous les avons, ne peuvent être comprises que dans le contexte de principes généraux orientés objet. Cela ne peut pas être compris séparément. Vous devrez probablement examiner la question sous cet angle, les choses pourraient devenir plus claires.
Nazar Merza


3
Si vous surprenez une personne utilisant une ceinture de sécurité dans sa voiture, vous devriez lui retirer son permis de conduire, car, de toute évidence, ils ne font pas confiance à leurs propres capacités de conduite.
gnasher729

Réponses:


307

Ce n’est pas tant une question de confiance que de gestion de la complexité.

Vous pouvez accéder à un membre public de l’extérieur de la classe, ce qui, pour des raisons pratiques, signifie «potentiellement n’importe où». Si quelque chose ne va pas avec un champ public, le coupable peut être n'importe où, et afin de pouvoir détecter le bogue, vous devrez peut-être consulter beaucoup de code.

Un membre privé, en revanche, est accessible uniquement à partir de la même classe. Par conséquent, en cas de problème, il n’ya généralement qu’un seul fichier source à examiner. Si vous avez un million de lignes de code dans votre projet, mais que vos classes sont réduites au minimum, cela peut réduire votre effort de suivi des bogues d'un facteur 1000.

Un autre avantage est lié au concept de «couplage». Un membre public md'une classe Autilisée par une autre classe Bintroduit une dépendance: si vous modifiez min A, vous devez également vérifier les utilisations de min B. Pire encore, rien dans la classe ne Avous indique où mest utilisé, vous devez donc effectuer une nouvelle recherche dans toute la base de code; si vous écrivez une bibliothèque, vous devez même vous assurer que le code est en dehorsvotre projet ne rompt pas à cause de votre changement. En pratique, les bibliothèques ont tendance à conserver les signatures de leurs méthodes originales aussi longtemps que possible, aussi pénible soit-elles, et introduisent ensuite un bloc de modifications radicales avec une mise à jour majeure. Avec les membres privés, en revanche, vous pouvez exclure les dépendances immédiatement. Elles ne sont pas accessibles de l'extérieur. Toutes les dépendances sont donc contenues dans la classe.

Dans ce contexte, les "autres programmeurs" incluent votre futur et le passé. Vous savez sans doute maintenant que vous ne devriez pas faire cette chose X avec votre variable Y, mais vous avez forcément oublié trois mois plus tard lorsqu'un client a besoin de toute urgence d'implémenter une fonctionnalité, et vous vous demandez pourquoi faire une pause dans X Y de manière obscure.

Donc, pour ce qui est de savoir quand il faut rendre les choses privées: je dirais de tout rendre privé par défaut, puis d’exposer uniquement les parties qui doivent absolument être publiques. Plus vous pouvez rendre privé, mieux c'est.


24
+1 pour avoir été au cœur du problème, même si j’ai personnellement trouvé que mon code était plus facile à gérer lorsque j’arrêtais de passer en revue les étapes afin d’assurer la confidentialité d’une variable fréquemment utilisée. Certes, une erreur peut survenir dans le futur, mais il reste 60 lignes de code en moins à filtrer et moins de variables et de fonctions à initialiser;)
Jeffrey Sweeney

48
Le Saint Graal de l'informatique moderne réduit la complexité.

1
J'aime toujours dire qu'une partie du débogage ne consiste pas simplement à rechercher directement «ce qui a mal tourné», mais à prendre le processus détourné consistant à déterminer «ce qui n'a pas mal tourné» et à concentrer mon enquête sur ce qui reste. Si je peux obtenir que le compilateur m'aide avec des outils tels que les variables privées pour définir «ce qui ne peut pas s'être passé», cela me fait gagner beaucoup de temps. Ce n'est que dans les rares cas où je prouve que rien ne s'est mal passé que je dois creuser dans des hypothèses plus effrayantes, comme par exemple un dépassement de mémoire tampon écrasant mes données privées.
Cort Ammon

2
Exactement ça. Quand les gens entendent "cacher de l'information", ils pensent qu'ils devraient utiliser des variables privées pour des éléments tels que les clés de cryptage, les informations d'identification de base de données, etc.
Wayne Werner

2
@AdamZerner voir "Dis, ne pose pas de questions" ( martinfowler.com/bliki/TellDontAsk.html ) sur le fait d'avoir des getters / setters en premier lieu - mais sinon, oui, car vous devriez être libre de changer la représentation interne de la valeur à tout moment. tu souhaites. Comme toujours, il y a des exceptions ... (par exemple DTO)
DoubleYou

111

Les variables privées empêchent les utilisateurs de dépendre de certaines parties de votre code. Par exemple, supposons que vous souhaitiez implémenter une structure de données. Vous voulez que les utilisateurs de votre structure de données ne se soucient pas de la façon dont vous l' avez implémentée, mais utilisez simplement cette implémentation via votre interface bien définie. La raison en est que si personne ne dépend de votre implémentation, vous pouvez le changer à tout moment. Par exemple, vous pouvez modifier l'implémentation dorsale pour améliorer les performances. Tous les autres développeurs qui dépendent de vos implémentations tomberont en panne, tandis que les utilisateurs de l'interface iront bien. Avoir la souplesse nécessaire pour modifier les implémentations sans affecter les utilisateurs de la classe est un avantage énorme que l'utilisation de variables privées (et plus généralement d' encapsulation ) vous confère.

En outre, ce n'est pas vraiment une "crise de confiance". Si vous rendez une donnée publique, vous ne pouvez pas vous assurer que personne n'en dépend. Il est souvent très pratique de dépendre d'une variable spécifique à une implémentation, au lieu de passer par l'interface publique, en particulier au plus fort d'une échéance. De plus, les développeurs ne réalisent pas toujours qu'ils dépendent de quelque chose qui pourrait changer.

Donc, ce genre de réponse à vos autres questions, j'espère. Tous les détails de votre implémentation doivent être privés et la partie publique doit être une petite interface concise et bien définie pour utiliser votre classe.


24
IMO, c'est aussi une question de communication entre l'auteur et le consommateur. L’interface publique ressemble à «utiliser ceci» et les privatifs à «ne pas utiliser cela», sauf qu’en Java, vous ne pouvez vraiment pas l’utiliser par accident si vous le rendez privé afin que ce soit plus sûr et plus clair.
chakrit

5
@chakrit et autres: Notez que ceux qui veulent vraiment utiliser vos champs et méthodes privés peuvent le faire (par réflexion). privateest inférieur à "pas principalement destiné à la sécurité", il ne fournit aucune "sécurité" à proprement parler. C'est juste un conseil fort (fourni par le compilateur) de ne pas y accéder.

@Delnan noter la phrase «par accident» ouais peut-être que je devrais être plus clair à ce sujet.
chakrit

@chakrit Oui, je ne voulais pas dire que vous aviez tort. Je voulais juste promouvoir ce point.

1
@delnan: les champs privés fournissent, dans certaines langues, certaines formes de sécurité. Par exemple, voir la réponse d'Eric Lippert à la rubrique Les niveaux d'accès et les modificateurs (privé, scellé, etc.) servent-ils un objectif de sécurité en C #? .
Brian

25

Le mot clé ici est Encapsulation . Dans la programmation orientée objet, vous souhaitez utiliser des variables privées pour appliquer une encapsulation correcte de vos objets / classes.

Bien que les autres programmeurs ne cherchent pas à vous obtenir, ils interagissent avec votre code. Si vous ne faites pas une variable privée, ils peuvent bien s'y référer dans leur propre code sans vouloir faire de mal. Cependant, si vous devez retourner dans votre classe et changer quelque chose, vous ne savez plus qui utilise quelle variable et où. Le but de l’encapsulation est de rendre explicite l’interface externe de la classe afin que vous sachiez que seules ces méthodes (généralement) auraient pu être utilisées par d’autres.

  1. Par conséquent, les variables privées garantissent que la variable correspondante reste uniquement dans la classe de définition. Si vous devez le changer, le changement est local pour la classe elle-même.

  2. Dans les langages traditionnels tels que C ++ ou Java, tout est généralement privé et accessible uniquement aux accesseurs. Pas besoin de décider beaucoup vraiment.

  3. Parfois, f.ex. dans une structure C ++, vous n'avez besoin d'une classe que pour regrouper plusieurs éléments. Par exemple, considérons une classe Vector qui a xun yattribut et un attribut uniquement. Dans ces cas, vous pouvez autoriser un accès direct à ces attributs en les déclarant publics. En particulier, vous ne devez pas vous soucier de savoir si du code extérieur modifie un objet de votre classe en écrivant directement de nouvelles valeurs dans xou y.

En outre, notez que cette question est considérée comme légèrement différente dans d’autres langues. Par exemple, les langages fortement enracinés dans la programmation fonctionnelle insistent sur l’immuabilité des données, c’est-à-dire que les valeurs des données ne peuvent pas être modifiées du tout. Dans de tels cas, vous ne devez pas vous soucier de ce que les autres programmeurs (ou plutôt leur code) font de vos données. Ils ne peuvent tout simplement rien faire qui puisse affecter votre code, car toutes les données sont immuables.

Dans ces langues, vous obtenez donc ce que l’on appelle le principe d’accès uniforme , selon lequel on ne distingue pas délibérément des méthodes telles que les accesseurs, mais aussi un accès direct à la variable / fonction. Vous pouvez donc dire que les déclarations privées sont beaucoup plus populaires dans les scénarios orientés objet.

Cela montre également comment élargir vos connaissances pour inclure d'autres domaines vous permet de voir les concepts existants d'une toute nouvelle façon.


1
+1 "Bien que les autres programmeurs ne cherchent pas à vous obtenir, ils interagissent avec votre code." Les programmeurs utilisant votre code ne sont pas fondamentalement pervers. En utilisant des variables privées, vous vous assurez qu'elles ne seront pas blessées (et vous, à l'avenir) en utilisant le code. Cela vous aide également à concevoir une meilleure API et à la documenter.
szalski

7

Les variables privées garantissent que les références ultérieures en dehors de la portée d'un objet ou d'une fonction n'affecteront pas par inadvertance d'autres variables. Pour les grands projets de programmation, cela peut aider à éviter beaucoup de problèmes intéressants (qui ne sont généralement pas résolus par le compilateur).

Par exemple, des langages prototypiques tels que Javascript peuvent permettre aux utilisateurs de plâtrer des variables comme bon leur semble:

function SomeObject() {
    this.a = 2; //Public (well, actually protected) variable

    this.showA = function() {
        alert(this.a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 3. Uh oh!

Si cette variable était privée, elle ne pourrait pas être modifiée de l'extérieur:

function SomeObject() {
    var a = 2; //Private variable

    this.showA = function() {
        alert(a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 2

Cela dit, toutes les variables ne doivent pas nécessairement être privées et un usage excessif de celles-ci peut en réalité alourdir le code. Les champs triviaux qui n'ont pas d'impact sérieux sur un objet n'ont pas besoin de méthodes get()ni de set()méthodes.

Les variables privées facilitent également l’extension future du code, sans avoir à s’appuyer sur une documentation exhaustive sur le rôle des nombreuses variables publiques. Il y a moins de risque de rupture accidentelle des fonctionnalités si moins de variables peuvent être écrasées.

Les variables publiques doivent être utilisées lorsqu'un objet / une fonction va accéder à d'autres objets / fonctions, car les variables privées ne peuvent généralement pas le faire. Vous avez peut-être quelques variables publiques, et ce n’est pas une mauvaise chose de les utiliser si elles sont utilisées correctement.


Ce n'est pas évident pourquoi alerter 3 serait un "euh oh!" dans ce cas. Peut-être que c'est ce que le programmeur voulait arriver.
Immibis

@immibis Peut-être, et j'aurais peut-être dû élaborer davantage dans la réponse. Mais l'accès aux propriétés peut ouvrir la porte à la violation de certains principes de la POO tels que le principe d'ouverture / fermeture ou le LoD, car vous exposez potentiellement des détails de mise en œuvre. Bien sûr, cela dépend de ce que la propriété est exactement. La plupart des langages utilisent des objets comme références. Lorsque les références d'objets sont échangées et que les autres développeurs changent de propriétés en silence, il peut être VRAIMENT difficile à déboguer. IMO il est beaucoup plus facile et plus extensible de travailler avec des méthodes si vous avez une instance de classe.
Jeffrey Sweeney

7

Il y a quelques bonnes réponses citant les avantages pour les futurs responsables et les utilisateurs d'une classe. Cependant, la conception d'origine présente également des avantages. Il fournit un point de démarcation clair entre le moment où votre objectif est de vous rendre la tâche plus facile et le but de faciliter les choses pour l'utilisateur de la classe. Lorsque vous choisissez entre public et privé, cela signale à votre cerveau de basculer vers un mode ou un autre, et vous obtenez une meilleure API.

Ce n'est pas que les langues sans vie privée rendent un tel design impossible, mais moins probable. Au lieu d’être incités à écrire quelque chose comme cela foo.getBar(), les gens sont enclins à penser qu’un getter n’est pas nécessaire, car c’est plus facile à écrire foo.bar, mais cette décision n’est pas revue lorsque vous vous retrouverez avec des monstruosités plus longues obj.container[baz].foo.bar. Les programmeurs qui n'ont jamais travaillé dans un langage plus strict peuvent même ne pas voir ce qui ne va pas avec cela.

C'est pourquoi, dans les langues sans vie privée, les gens adoptent souvent des normes de nommage qui le simulent, telles que l'ajout d'un soulignement à tous les membres "privés". C'est un signal utile même lorsque le langage ne l'impose pas.


3

Toutes les variables doivent être privées sauf si elles doivent absolument être publiques (ce qui n’est presque jamais, vous devez utiliser des propriétés / accesseurs et des setters).

Les variables fournissent en grande partie l'état de l'objet et les variables privées empêchent les autres d'entrer et de modifier l'état de l'objet.


5
Une vision trop étroite du sujet. Il existe des cas où l'accès public aux champs est justifié, voire préféré
Roland Tepp

On peut certes concevoir des objets dont l'état ne peut pas être changé (objets immuables), mais ce n'est pas une règle générale appliquée à toutes les classes. D'après mon expérience, la plupart des objets permettent très facilement aux autres de modifier l'état de l'objet.
David K

1
@DavidK Peut-être que ce que bbb voulait dire, c'est que "les variables privées empêchent les autres d'entrer et de modifier indistinctement l'état de l'objet." Les méthodes publiques peuvent modifier l'état privé de l'objet, mais uniquement de manière nécessaire et cohérente pour le fonctionnement de l'objet.
Max Nanasy

@ Max Nanasy: Oui, on peut contrôler la manière dont l'état est modifié lorsque l'on propose uniquement des méthodes dans l'interface publique. Par exemple, il peut exister une relation entre les membres qui doit être satisfaite pour que l'objet soit "cohérent", et vous pouvez autoriser la modification d'un état cohérent uniquement vers un autre état cohérent. Si toutes ces variables sont publiques, vous ne pouvez pas appliquer cela. Mais il peut aussi y avoir des objets pour lesquels vous ne voulez permettre aucun changement, il est donc important de préciser lequel de ces sujets dont nous parlons.
David K

2
  • Qu'est-ce que les variables privées aident à prévenir?

Il s'agit de préciser quelles propriétés et quelles méthodes sont une interface et quelles sont en réalité les fonctionnalités principales. Les méthodes / propriétés publiques concernent un autre code, souvent le code d'un autre développeur utilisant vos objets. Je n'ai jamais travaillé sur des équipes de plus de 100 personnes sur le même projet, mais dans mon expérience de 3 à 5 équipes avec jusqu'à 20 autres développeurs utilisant des éléments que j'ai écrits, les autres préoccupations semblent ridicules.

Remarque: je suis principalement un développeur JavaScript. Je ne m'inquiète généralement pas du fait que d'autres développeurs voient mon code et je suis conscient du fait qu'ils pourraient simplement redéfinir mes informations à tout moment. Je suppose qu'ils sont suffisamment compétents pour savoir ce qu'ils font en premier. Sinon, il est peu probable que je travaille dans une équipe qui n'utilise pas le contrôle de source.

  • Comment décidez-vous si un ensemble particulier de propriétés doit être privé ou non? Si par défaut chaque champ DEVRAIT être privé, alors pourquoi y a-t-il des données membres dans une classe?

J'avais l'habitude de penser que c'était idiot de placer des getters et des setters sur des propriétés privées alors que vous ne réalisiez pas de validation ou autre traitement spécial de la propriété à définir. Je ne pense toujours pas que ce soit toujours nécessaire, mais lorsque vous traitez avec une grande complexité, mais surtout de nombreux autres développeurs utilisant des objets se comportant de manière cohérente, il peut être utile de faire les choses de manière cohérente. manière cohérente et uniforme. Quand les gens voient des méthodes appelées getThatetsetThat, ils savent exactement quelles sont leurs intentions et ils peuvent écrire leurs objets pour interagir avec les vôtres dans l’espoir de toujours avoir des tomates plutôt que des tomahtos. S'ils ne le font pas, ils savent que votre objet leur fournit quelque chose qu'il ne devrait probablement pas, ce qui signifie qu'il permet à un autre objet de faire quelque chose avec ces données, mais qu'il ne devrait probablement pas. Vous pouvez contrôler cela au besoin.

L'autre grand avantage est qu'il est plus facile de laisser vos objets céder ou interpréter les valeurs différemment d'un getter ou d'un setter en fonction d'un type de contexte d'état variable. Comme ils accèdent à vos données avec une méthode, il est beaucoup plus facile de modifier le fonctionnement ultérieur de votre objet sans interrompre le code qui en dépend. Le principe important est que seul votre objet change réellement les données que vous lui confiez. Ceci est particulièrement important pour garder votre code faiblement couplé, ce qui représente un gain considérable en termes de portabilité et de facilité de modification.

  • Dans quelles circonstances une variable devrait-elle être rendue publique?

Avec des fonctions de première classe (vous pouvez passer de fonctions sous forme d'arguments), je ne vois pas beaucoup de bonnes raisons, à part le fait qu'il n'est pas absolument nécessaire de le faire sur des projets de plus petite envergure. Sans cela, je suppose que vous pourriez avoir des membres qui sont traités de manière intensive et régulière par d'autres objets, au point qu'il semble un peu cruel d'appeler constamment get et sets sur un objet qui ne touche pas vraiment ces données, lui-même me ferait me demander pourquoi l'objet était responsable de ces données. D'une manière générale, j'aurais tendance à vouloir réexaminer mon architecture à la recherche de failles avant de décider qu'une propriété de données publique est nécessaire. OMI, il n'y a rien de mal avec une langue vous permettant de faire quelque chose qui est généralement une mauvaise idée. Certaines langues ne sont pas d'accord.


IMHO, il n'y a rien de mal à avoir une classe publique dont le seul but est d'exposer des variables publiques. En effet, la machine virtuelle Java a un certain nombre de classes intégrées à cet effet: int[], double[], Object[], etc. Il ne faut cependant faire très attention à la façon dont on expose les instances d'une telle classe. Le sens de void CopyLocationTo(Point p);[accepter Pointl'appel de l'appelant] est plus clair que Point location(), puisqu'il n'est pas clair quel effet Point pt = foo.location(); pt.x ++;aura sur l'emplacement de foo.
Supercat

2

Voir ce post de mon à une question connexe sur SO .

En bref, la portée variable vous permet de montrer aux utilisateurs de votre code ce qu’ils devraient et ne devraient pas jouer avec. Une variable privée peut contenir des données "vérifiées" à l'aide d'un configurateur de propriétés ou d'une méthode de traitement afin de garantir la cohérence de l'ensemble de l'objet. Changer directement la valeur de la variable privée peut rendre l’objet incohérent. En le rendant privé, quelqu'un doit travailler très dur et disposer d'autorisations d'exécution très élevées pour le changer.

La délimitation correcte des membres est donc essentielle dans le code auto-documenté.


2

Je vais parler de la valeur de l'encapsulation sous un angle différent en utilisant un exemple réel. Il y a quelque temps (au début des années 80), un jeu a été écrit pour l'ordinateur couleur Radio Shack appelé Dungeons of Daggorath. Il y a quelques années, Richard Hunerlach l'a transféré d'une liste d'assembleurs de papier au C / C ++ ( http://mspencer.net/daggorath/dodpcp.html ). Quelque temps plus tard, j'ai reçu le code et commencé à le re-factoriser pour améliorer l'encapsulation ( http://dbp-consulting.com/stuff/ ).

Le code était déjà pris en compte dans différents objets pour gérer la planification, la vidéo, les entrées utilisateur, la création de donjons, les monstres, etc., mais vous pouviez certainement dire qu'il était porté par l'assembleur. Ma tâche la plus importante était d'augmenter l'encapsulation. J'entends par là obtenir différentes parties du code afin que leurs affaires ne se mêlent plus. Par exemple, il y avait beaucoup d'endroits où les variables vidéo étaient directement modifiées pour avoir un effet. Certains l'ont fait en vérifiant les erreurs, d'autres non, d'autres avaient des idées légèrement différentes sur la signification de changer cette chose. Il y avait beaucoup de duplication de code. Au lieu de cela, la section vidéo avait besoin d'une interface pour accomplir les tâches souhaitées, et le code pour le faire pourrait être situé au même endroit, une idée, un endroit pour le débogage. Ce genre de chose était endémique.

Alors que le code commençait à être mis à part, les bugs qui n'avaient même pas été diagnostiqués ont disparu. Le code est devenu de meilleure qualité. Chaque tâche devenait la responsabilité d'un endroit dans le code et il n'y avait qu'un endroit pour bien faire les choses. (J'en trouve encore plus chaque fois que je fais un autre passage dans le code.)

Tout ce qui est visible sur votre code est votre interface. Que vous le pensiez ou non. Si vous limitez autant que possible la visibilité, vous ne serez pas tenté de placer le code au mauvais endroit plus tard. Cela indique clairement quelle partie du code est responsable de quelles données. Il en résulte un design meilleur, plus propre, plus simple et plus élégant.

Si vous rendez un objet responsable de ses propres données et fournissez des interfaces à tous les autres qui ont besoin de quelque chose, votre code devient beaucoup plus simple. Ça tombe juste. Vous avez de petites routines simples qui ne font qu'une chose. Moins de complexité == moins de bugs.


Le dur équilibre entre "la liberté de nos utilisateurs de la bibliothèque" et "moins de problèmes pour nous". Je commence à croire que l’encapsulation est préférable, dans le sens où je préviendrai les bogues sur mon propre code et que je vais aider les utilisateurs finaux à les prévenir également. Mais le manque de liberté peut tout simplement les éloigner également, à la recherche d'alternatives ... Le codage n'est peut-être pas encore utilisé, mais les fonctionnalités prévues par les méthodes publiques peuvent aider à équilibrer cela, mais demandent plus de temps.
Aquarius Power

Dommage que la version refactorisée ne soit pas sur github ....
jmoreno

2

Cela n'a rien à voir avec la confiance ou la peur des attaques, il s'agit uniquement d'encapsulation - ne pas imposer d'informations inutiles à l'utilisateur de la classe.

Considérez les constantes privées - elles ne doivent pas contenir de valeurs secrètes (celles-ci doivent être stockées ailleurs), elles ne peuvent pas être modifiées, elles n'ont pas besoin d'être passées dans votre classe (sinon elles devraient être publiques). Leur seule utilisation est comme constantes dans les autres classes. Mais si vous faites cela, ces classes dépendent maintenant de votre classe pour faire un travail qui n’a aucun rapport avec votre classe. Si vous modifiez la constante, d'autres classes risquent de se rompre. C'est mauvais des deux côtés - en tant qu'écrivain de votre classe, vous voulez la liberté de changer le plus possible et ne vous souciez pas de choses indépendantes de votre volonté. Un consommateur de votre classe veut pouvoir compter sur les détails exposés de votre classe, sans vous soucier de le modifier ou de casser son code.

Un consommateur de votre classe veut savoir tout ce qui est nécessaire pour interagir avec votre classe et ne veut rien savoir de votre classe qui ne change pas la façon dont il le fait: c'est une anecdote inutile. Si vous avez utilisé une langue avec réflexion, combien de fois l'avez-vous utilisée pour apprendre non pas comment une classe fait quelque chose ou où elle lève une exception de manière inattendue, mais simplement le nom des champs et des méthodes privés? Je parie jamais. Parce que vous n'avez aucune utilité pour cette connaissance.


1

Le concept de POO a l'héritage a l'une de ses caractéristiques (Java ou C ++). Donc, si nous allons hériter (c'est-à-dire que nous allons accéder aux variables de la classe héritée), il est possible d'affecter ces variables. Nous devons donc décider si les variables peuvent être modifiées ou non.

À cette fin uniquement, nous utilisons des modificateurs d'accès dans la programmation orientée objet. L'un des modificateurs est privé, ce qui signifie qu'il n'est accessible que par cette classe. Toute autre classe ne peut affecter ces variables.

Comme nous le savons, protégé signifie que la classe qui va hériter peut y accéder.

Pourquoi y a-t-il un concept de modificateur dans la POO, cela tient à ces raisons (toute classe peut accéder à d'autres variables de classe en utilisant le concept de POO). S'il n'y a pas de concept de modificateur, cela signifie que cela aurait été difficile lors de l'héritage de classes ou de l'utilisation d'autres concepts de POO.


1

Comme indiqué par d'autres, les variables privées sont utiles pour éviter les utilisations erronées, ce qui pourrait rendre l'état de l'objet incohérent et rendre difficile le suivi des bogues et des exceptions imprévues.

Mais dans l’autre côté, ce qui a été en grande partie ignoré concerne les champs protégés.

Une sous-classe étendue aura un accès complet aux champs protégés, rendant l'objet aussi fragile que si ces champs étaient publics, mais cette fragilité est limitée à la classe étendue elle-même (à moins qu'elle ne les expose encore plus).

Il est donc difficile de considérer que les champs publics sont bons, et à ce jour, la seule raison de les utiliser est celle des classes utilisées comme paramètre de configuration (une classe très simple avec de nombreux champs et aucune logique, de sorte que la classe est passée en paramètre uniquement à une méthode).

En revanche, les champs privés réduisent la flexibilité de votre code pour les autres utilisateurs.

Flexibilité vs problèmes, avantages et inconvénients:

Les objets instanciés par votre code dans la classe vanilla avec des champs protégés sont en sécurité et relèvent de votre entière responsabilité.

D'autre part, les objets étendant votre classe avec des champs protégés, instanciés par les utilisateurs de votre code, relèvent de leur responsabilité et non de la vôtre.

Par conséquent, les champs / méthodes protégés mal documentés, ou si les utilisateurs ne comprennent pas vraiment comment ces champs et méthodes doivent être utilisés, risquent de causer des problèmes inutiles à eux-mêmes et à vous-même.

D'un autre côté, rendre la plupart des choses privées réduira la flexibilité des utilisateurs et les mettra peut-être même à la recherche d'alternatives maintenues, car ils ne voudront peut-être pas créer et maintenir une fourchette juste pour que les choses se passent bien.

Donc, ce qui compte vraiment, c'est un bon équilibre entre privé, protégé et public.

Maintenant, décider entre privé et protégé est le vrai problème.

Quand utiliser protégé?

Chaque fois que vous comprenez qu'un champ peut être très flexible, il doit être codé comme protégé. Cette flexibilité est la suivante: de devenir null (où null est toujours vérifié et reconnu comme un état valide ne générant pas d'exceptions), à avoir des contraintes avant d'être utilisé par votre classe ex. > = 0, <100, etc., et fixé automatiquement pour les valeurs de dépassement / de sous-débit, générant tout au plus un message d'avertissement.

Donc, pour un tel champ protégé, vous pouvez créer un getter et l’utiliser uniquement (au lieu d’utiliser directement la variable de champ), alors que d’autres utilisateurs ne peuvent pas l’utiliser, s’ils veulent plus de flexibilité pour leur code spécifique, dans mon exemple, pourrait ressembler à : s'ils veulent que les valeurs négatives fonctionnent correctement dans leur classe étendue.


-1

imo @tdammers n’est pas juste et est en réalité trompeur.

Des variables privées existent pour masquer les détails de la mise en œuvre. Votre classe Apourrait utiliser un arraypour stocker des partitions. Demain, vous voudrez peut-être utiliser un treeou à la priority queueplace. Tous les utilisateurs de votre classe ont besoin d’un moyen de saisir les scores et les noms, addScore()ainsi que de déterminer les 10 meilleurs getTop(n).

Ils n'ont pas besoin d'accéder à la structure de données sous-jacente. Super? Eh bien, il y a des mises en garde.

De toute façon, vous ne devriez pas stocker beaucoup d’états, la plupart ne sont pas nécessaires. L'enregistrement d'état compliquera votre code même s'il est "séparé" d'une classe spécifique. Pensez-y, cette variable privée a probablement changé car un autre objet appelé méthode de cette classe. Vous devez toujours déterminer quand et où cette méthode a été appelée et cette méthode publique peut être appelée n'importe où théoriquement.

La meilleure chose à faire est de limiter la quantité d’états que contient votre programme et d’utiliser des fonctions pures lorsque cela est possible.


-1
  • Accéder à une variable signifie accéder à sa valeur lors de l'exécution du programme, ce qui rend une variable privée protège sa valeur lors de l'exécution du code.
  • L'intérêt de ce qu'on appelle "masquage des données" est de garder les données internes cachées aux autres classes qui utilisent la classe. Ces autres classes ne doivent accéder au comportement qu'en appelant des méthodes sur la classe, et non en modifiant directement les valeurs des variables.
  • En faisant de la variable un membre de données privé, vous pouvez plus facilement vous assurer que la valeur ne sera jamais modifiée. D'autre part, si la variable est publique, une autre classe peut modifier ou modifier la valeur, ce qui peut entraîner le blocage d'autres parties du code.

1
cela ne semble pas offrir quoi que ce soit de substantiel sur les points soulevés et expliqués dans les 17 réponses précédentes
gnat

-4

Vous devez d’abord comprendre le concept de programmation orientée objet. Il a l'abstraction, l'encapsulation, etc.

Abstraction - Vous obtenez l’idée de la logique sans avoir besoin de connaître les détails soulignés de la mise en oeuvre.

Encapsulation - Vous ne pouvez pas voir l'implémentation soulignée de l'objet. Seul vous pouvez voir l'interface publique de l'objet.

Maintenant, dans une implémentation spécifique avec l'un des programmes orientés objet tels que C #, Java, C ++, vous pouvez implémenter ces concepts.

private - La mise en œuvre qui doit être cachée du monde extérieur. Pour que vous puissiez changer cela et que l'utilisateur de votre classe ne soit pas affecté.

public - C'est l'interface par laquelle on peut utiliser votre objet.


1
protected - directement accessible par sous-classes (extendeurs) (java).
Aquarius Power
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.