2010-09-16 81 views
5

我是一个新的程序员,所以请原谅这个问题的任何愚蠢,下面的代码是如何封装私人数据? -封装在哪里?

public class SomeClass 
{ 
    private int age; 

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

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

我的意思是,与在属性没有限制逻辑或过滤逻辑,如何在上述代码从如下因素一个不同 -

public class SomeClass 
{ 
    public int age; 

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

是对第一代码提供任何封装在所有?

回答

8

它提供了一个封装:它说:“有一个Age属性,你可以获取和设置,但我不会告诉你如何实现它。”

这不是很强大的封装,但它确实保持与公共API的实现细节分开。在根本不改变公共API的情况下,您可以开始将年龄存储在其他地方 - 在short两个字段中,在某个地方的某个服务中,作为long字段或其他内容的一部分。您可以将日志记录放在属性中以查看它使用的频率。您可以添加一个事件,在年龄发生变化时触发(这是一个API更改,但不会破坏现有的呼叫者)。

编辑:有一点需要注意:尽管现在没有做任何事情,但对的更改使得以后做的事情既是源代码又是二进制兼容。将字段更改为属性是而不是向后兼容,无论是源代码还是二进制形式。在大多数的情况下,它将是源兼容的,但不是二进制兼容的。在某些情况下,源代码将不再构建。在更邪恶的(并且人为的,无可否认)两个版本都会建立起来,但具有不同的效果。

另外请注意,由于C#3,你可以很容易地作为一个申报财产琐碎作为一个字段:

public int Age { get; set; } 

我有一个article about all of this提供更多的细节。

+0

...但它是通过任何手段 “保护” 我的私人数据?我认为保护私人数据是封装服务的一个重要目的:( – atiyar 2010-09-16 15:21:13

+1

封装使您能够保护您的私人数据,就像说:“当我用这把锤子敲击这些岩石时,怎么会发生什么事?我以为锤子是为了建筑“这只是一个工具,它不会强制你使用它。 – recursive 2010-09-16 15:27:42

+1

@Nero:它可以是关于数据......它可以是关于实现的细节,它们都是封装的一部分。 – 2010-09-16 16:09:19

0

在您的第一个示例中,SomeClass.Age是一个属性。 “支持”财产的领域是私人的。在你的第二个例子中,SomeClass.age是一个公共字段。虽然在很多情况下可能没有区别,但在字段上选择属性可让您在不更改API或类的“形状”的情况下更改实现。也许你想在财产发生变化时做一些事情(坚持或通知) - 这对于一个领域来说是不可能的。

+0

你可以很容易地把该领域变成一个属性;-) – 2010-09-16 15:18:36

+1

有差异。属性不能作为'ref'传递。字段不能被数据绑定。 – recursive 2010-09-16 15:28:24

2

这是一个空洞的例子。正如您已经正确指出的那样,该物业似乎没有做任何事情。

但它可以。例如,SomeClass可以对Age属性的修改方式加以限制(例如,不要将年龄更改为-2或823等错误值)。此外,SomeClass不需要在内部将年龄表示为int。年龄可能是计算的结果(比如说从一个人的出生日期中减去今天的日期),或者它可以作为另一种数据类型(比如一个字节,长或者双)存储在SomeClass中。

+0

这就是很多“可能”,男人。我正在询问代码,因为它现在是“是”。因为我看到很多代码(不是专家的),就像我说的那样,私人领域和公共财产没有限制逻辑。是不是属性应该提供某种封装来保护我的私人数据?如果他们不这样做,那么这两个代码样本之间是否有区别?多数民众赞成在所有我问,因为我没有任何想法。 – atiyar 2010-09-16 16:01:13

+0

@Nero:我不知道你为什么说“不是专家” - 在某些情况下,一个公开可写,琐碎的财产是正确的。它比公共领域还要好。 – 2010-09-16 16:10:10

+0

@Nero:是的,财产和公共领域之间的语义差异很小,但这并不重要。良好的软件工程的重点不仅仅是编写可行的代码,它是编写可理解和可扩展的代码。因此,“可能”与“是”的含义一样重要。 – joshdick 2010-09-20 13:17:03

2

我的意思是,在性质没有限制逻辑或过滤逻辑,是如何从如下因素一个

它不是事实,你已经被或尚未实施的验证逻辑上面的一个不同在这里,封装意味着没有人可以直接访问/修改你的私人数据。唯一可用的访问是通过该财产。

使用底部代码,任何人都可以引发异常并导致各种破坏,因为他们可以对数据做任何他们想做的事情。

使用顶级代码作为其写入允许这种相同的破坏,但在将来的任何时候,您都可以在属性中实现限制逻辑,而无需为此类的用户修改API。

1

它封装或封装对私有变量age的更改。私人变量Age不能由外部调用者直接修改,只能通过给出的public方法修改。它正在设置一个接口,以便将来对age所做的更改不会中断呼叫者。未来的好处是外部呼叫者,这就是为什么现在很难看到。

0

是第一个提供任何封装的代码吗?

否(至少是您编写的特定代码)。

2段代码几乎相同。第一个与第二个不同(与编写代码相比)没有提供任何有用的区别。

当使用获取者和设置者时,可以限制访问私有变量。这可能是一种封装形式。

private int x 

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