2010-09-16 4 views
5

Je suis un nouveau programmeur, alors s'il vous plaît excusez toute idiot de cette question, comment le code suivant encapsule des données privées? -Où est l'encapsulation?

public class SomeClass 
{ 
    private int age; 

    public int Age 
    { 
     get { return age; } 
     set { age = value; } 
    } 

    public SomeClass(int age) 
    { 
     this.age = age; 
    } 
} 

Je veux dire, sans logique de restriction ou de la logique de filtrage dans les propriétés, comment est le code ci-dessus différent du folowing un -

public class SomeClass 
{ 
    public int age; 

    public SomeClass(int age) 
    { 
     this.age = age; 
    } 
} 

est le premier code fournit une encapsulation du tout?

Répondre

8

Il fournit un élément d'encapsulation: il dit, "il y a une propriété Age que vous pouvez obtenir et définir, mais je ne vais pas vous dire comment je l'implémente."

Ce n'est pas une encapsulation très forte, mais conserve les détails d'implémentation séparément de l'API publique. Sans changer l'API publique du tout, vous pouvez commencer à stocker l'âge ailleurs - dans deux champs short, dans un service quelque part, dans le cadre d'un champ long ou autre. Vous pouvez mettre en connexion dans la propriété pour voir à quelle fréquence il est utilisé. Vous pouvez ajouter un événement qui se déclenche lorsque l'âge change (c'est un changement d'API, mais ne casse pas les appelants existants).

EDIT: Une chose à noter: même si cela ne fait rien maintenant, le changement à fait faire quelque chose plus tard est à la fois source et binaire compatible. La modification d'un champ pour devenir une propriété est et non rétrocompatible, sous forme source ou binaire. Dans le plus cas, il sera compatible avec la source, mais pas compatible binaire. Dans certains cas, la source ne sera plus construite. En plus de mal (et artificiel, certes) les deux versions vont se construire, mais avec des effets différents.

Notez également que C# 3, vous pouvez déclarer une propriété triviale aussi facilement comme un champ:

public int Age { get; set; } 

J'ai un article about all of this qui fournit plus de détails.

+0

... mais est-ce par tout moyen "protéger" mes données personnelles? Je pensais que la protection des données privées était un objectif important que l'encapsulation sert :( – atiyar

+1

L'encapsulation vous donne la possibilité de protéger vos données privées C'est comme dire "Comment se fait-il que rien ne se passe quand je frappe ces roches avec ce marteau? Ce n'est qu'un outil, il ne va pas vous forcer à l'utiliser de manière sensée – recursive

+1

@Nero: Il peut s'agir de données ... il peut s'agir de détails de mise en œuvre.Les deux font partie de l'encapsulation –

0

Dans votre premier exemple, SomeClass.Age est une propriété. Le champ "support" de la propriété est privé. Dans votre deuxième exemple, SomeClass.age est un champ public. Bien que, dans la plupart des cas, il n'y ait pas de différence, choisir une propriété sur un champ vous donne la possibilité de modifier l'implémentation sans modifier l'API ou la «forme» de la classe. Peut-être que vous voulez faire quelque chose (persister, ou notifier) ​​chaque fois que la propriété change - ce serait impossible à faire avec un champ.

+0

Vous pouvez transformer le champ en une propriété assez facilement ;-) –

+1

Il existe des différences. Les propriétés ne peuvent pas être passées comme 'ref'. Les champs ne peuvent pas être liés à des données. – recursive

2

Ceci est un peu un exemple vide. Comme vous l'avez noté correctement, la propriété ne semble rien faire.

Mais il pourrait. Par exemple, SomeClass pourrait mettre des restrictions sur la façon dont la propriété Age est modifiée (par exemple, ne pas changer l'âge à une mauvaise valeur comme -2 ou 823). De plus, SomeClass n'a pas besoin de représenter l'âge comme un int interne. L'âge pourrait être le résultat d'un calcul (en soustrayant la date d'aujourd'hui à la date de naissance d'une personne) ou pourrait être stocké dans SomeClass comme un autre type de données (par exemple un octet, long ou double).

+0

c'est beaucoup de "pourrait être", l'homme. Je demande à propos du code comme il est actuellement "IS". Parce que j'ai vu beaucoup de codes (pas d'expert, bien entendu) comme ça, comme je l'ai dit, domaine privé et propriété publique sans logique de restriction. ne sont pas des propriétés censées fournir une sorte d'encapsulation pour protéger mes données privées? et s'ils ne le font PAS, y a-t-il une différence entre les deux échantillons de code présentés?C'est tout ce que je demande parce que je n'ai aucune idée. – atiyar

+0

@Nero: Je ne sais pas pourquoi vous dites "pas expert" - dans certains cas, une propriété publique inscriptible, trivial est exactement la bonne chose à avoir. C'est toujours mieux qu'un champ public. –

+0

@Nero: Oui, la différence sémantique entre une propriété et un champ public est minime, mais ce n'est pas ce qui compte. Le but d'une bonne ingénierie logicielle n'est pas seulement d'écrire du code qui fonctionne; c'est d'écrire du code compréhensible et extensible. Ainsi, ce qui «pourrait être» importe autant que ce qui «est». – joshdick

2

Je veux dire, sans logique de restriction ou de la logique de filtrage dans les propriétés, comment est-ce qui précède différent des folowing un

Ce ne est pas le fait que vous avez ou avez pas mis en œuvre la logique de validation dans la propriété, l'encapsulation signifie ici que personne ne peut directement accéder/modifier vos données privées. Le seul accès disponible est de passer par la propriété. En utilisant le code du bas, n'importe qui peut générer des exceptions et causer toutes sortes de ravages, car ils peuvent faire tout ce qu'ils veulent pour vos données. L'utilisation du code supérieur comme écrit permet le même havoc, mais à tout moment vous pouvez implémenter la logique de restriction dans la propriété et ne pas avoir à modifier une API pour les utilisateurs de cette classe.

1

Il encapsule ou enveloppe les modifications de la variable privée age. La variable privée Age ne peut pas être modifiée directement par les appelants externes, mais uniquement via les méthodes public indiquées. C'est la mise en place d'une interface de sorte que les changements futurs à age ne briseront pas les appelants. L'avantage est pour les appelants externes à l'avenir, ce qui est pourquoi il est difficile de voir maintenant.

0

Le premier code fournit-il une quelconque encapsulation?

NON (au moins le code particulier que vous avez écrit).

Les 2 morceaux de code sont presque les mêmes. Le premier ne fournit aucune différence utile par rapport au second (comme le code est écrit). Lorsque vous utilisez des getters et des setters, peut restreindre l'accès aux variables privées. Cela pourrait être une forme d'encapsulation.

à savoir

private int x 

public int getInt(String password){ 
if(password == 'RealPassword'){ 
    return x 
    } 
}