32 votes

Encapsulation - pourquoi en avons-nous besoin alors que les setters sont déjà publics?

L'Encapsulation est de cacher les données. J'aimerais savoir ce que certains de vraiment intéressant de réponses ici.

Quel est le point derrière le garder variables private quand on a déjà déclarer public setter pour les variables.

Je comprends l'utilisation de l'encapsulation, mais quand nous faisons la setters public quel est le point derrière le garder et les variables private, nous pouvons directement utiliser public des modificateurs d'accès

Est-ce parce que nous ne voulons pas que les autres sachent exactement de la même façon, nous sommes de stockage des données ou la gestion des données sur le back-end?

34voto

Konamiman Points 20578

Est-ce parce que nous ne voulons pas que les autres sachent exactement de la même façon, nous sommes le stockage des données ou la gestion des données sur le back-end?

Oui, c'est le point. Elle est liée aux notions d' abstraction et de se cacher de l'information aussi.

Vous disposer d'un setter que lorsqu'il est appelé par la classe client aura d'effet que vous avez documenté. Il n'est aucune de l'entreprise du client comment cet effet est réellement atteint. Êtes-vous la modification de l'un des attributs de classe? Ok, laisser le client sait qu', mais pas le fait que vous êtes réellement la modification d'une variable. Dans le futur, vous pourriez souhaitez modifier votre classe de sorte qu'au lieu d'une simple sauvegarde de variables qu'il utilise quelque chose de complètement différent (un dictionnaire d'attributs? Un service externe? Quoi que!) et le client ne se cassera pas.

Si votre setter est une abstraction que vous fournissez au client pour "modifier cet attribut de classe". Dans le même temps, vous êtes en cachant le fait que vous utilisez une variable interne, car le client n'a pas besoin de savoir qui fait.

(Note: j'utilise ici le mot "attribut" comme un concept générique, n'est liée à aucune béton langage de programmation)

26voto

ComicSansMS Points 12749

Je suis entièrement d'accord avec Konamiman de la réponse, mais je voudrais ajouter une chose:

Il ya des cas où vous ne voulez vraiment pas que l'abstraction. Et c'est bien.

Un simple exemple, je tiens à utiliser ici est une classe pour un 3-dimensions du flotteur vecteur:

class Vector3f {
public:
    float x;
    float y;
    float z;
};

Pourriez-vous faire de ces domaines privé et de fournir des setters à la place? Bien sûr, vous pourriez. Mais ici, vous pourriez dire que la classe est vraiment juste censé fournir un n-uplet de flotteurs et vous ne voulez pas de fonctionnalités supplémentaires. Ainsi, l'ajout de setters ne ferait que compliquer la classe et vous préférez laisser le champs public.

Maintenant, vous pouvez facilement construire des scénarios où cela pourrait vous mordre plus tard. Par exemple, vous pourriez obtenir un jour une exigence qu' Vector3fs ne sont pas autorisés à stocker NaNs et doit lever une exception si quelqu'un essaie de le faire. Mais tel un futur hypothétique problème ne devrait pas être suffisant pour justifier l'introduction de nouvelles abstractions.

C'est votre appel en tant que programmeur pour décider qui des abstractions faire sens pour le problème à la main et ceux qui ne ferait que nuire à votre façon de faire le travail. Inutile abstractions sont sur-l'ingénierie et va nuire à votre productivité, tout autant que de ne pas abstraire suffisamment.

Bas de ligne: Ne pas aveuglément l'utilisation poseurs de partout juste parce que quelqu'un a prétendu que c'est bien pratique. Au lieu de cela, penser le problème à portée de main et d'envisager les avantages et les inconvénients.

12voto

Jawad Points 208

Parce que par encapsulation de nous fournir un seul point d'accès. Supposons que vous définissez une variable et son setter comme suit

String username; 

public void setUsername(String username){
this.username = username;
}

Plus tard, vous aimez ajouter un peu de validation avant de définition du nom d'utilisateur de la propriété. Si vous définissez le nom d'utilisateur à 10 places en accédant directement à la propriété, alors vous n'avez pas de point d'accès unique et vous avez besoin de faire ce changement à 10 places. Mais si vous avez une méthode de définition puis en faisant un changement à un endroit où vous pouvez facilement atteindre le résultat.

7voto

zulkarnain Points 66

Réfléchissez à ceci : je suis représentant d'une vraie vie de l'objet, un Lion à travers une classe. Je ferais quelque chose comme ça.

class Lion {
    public int legs;
} 

Maintenant, ma classe est nécessaire par un autre développeur pour créer un objet et de définir ses jambes terrain de. Il en ferait quelque chose comme ça

Lion jungleKing = new Lion();
jungleKing.legs=15;

Maintenant, la question est, Java ne pas la contraindre à la configuration de n'importe quel nombre de plus de 4 comme le nombre de pattes pour cet objet. Ce n'est pas une erreur, et ça va fonctionner tout aussi bien. Mais c'est une logique gaffe, et le compilateur ne sera pas vous aider là-bas. De cette façon, un Lion peut avoir un numéro de jambes. Mais si nous écrivons le code de cette façon

class Lion {
    private int legs;
    public void setLegs(int legs){
        if(legs>4)
            this.legs=4;
        else this.legs=legs;
    } 
} 

Maintenant, vous n'aurez pas de Lion avec plus de 4 pattes, car la stratégie de mise à jour les champs de la classe a été définie par la classe elle-même et il n'y a aucun cas, une personne ne connaissant pas la politique va mettre à jour les jambes terrain parce que la seule façon de mettre à jour les jambes champ est à travers la setLegs() la méthode et la méthode connaît la politique de la classe.

6voto

InBetween Points 6162

Bien que Konamiman's réponse est sur place, je tiens à ajouter que, dans le cas particulier des publics les setters rapport exposer directement les champs publics que vous posez, il y a une autre distinction très importante à garder à l'esprit en dehors de se cacher de l'information et de découplage de la mise en œuvre à partir de la surface publique, ou de l'API, d'une classe; la validation.

Dans un champ public scénario, il n'y a aucun moyen de valider la valeur du champ lorsqu'il est modifié. Dans le cas d'un public setter (que ce soit une Foo {get; set;} propriété ou un SetFoo(Foo value)) méthode que vous avez la possibilité d'ajouter un code de validation et lancement requis, effets secondaires et de cette façon vous assurer que votre classe est toujours valide ou prévisible de l'état.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X