我是一名新程序员,所以请原谅这个问题的任何愚蠢,以下代码如何封装私人数据? -
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;
}
}
第一个代码是否提供任何封装?
答案 0 :(得分:8)
它提供了一个封装:它说,“你可以获取和设置Age属性,但我不会告诉你我是如何实现它的。”
这不是非常强大的封装,但它确实将实现细节与公共API分开。在根本不更改公共API的情况下,您可以开始将年龄存储在其他地方 - 在两个short
字段中,在某个地方的服务中,作为long
字段的一部分或其他任何内容。您可以在该属性中记录日志以查看它的使用频率。你可以添加一个在年龄变化时被触发的事件(这是一个API更改,但不会破坏现有的调用者)。
编辑:有一点需要注意:即使现在什么也没做,但是 make 之后做的更改是源和二进制兼容的。将字段更改为属性不向后兼容,无论是源格式还是二进制格式。在大多数情况下,它将与源代码兼容,但不兼容二进制。在某些情况下,源将不再构建。在更邪恶(并且设想,不可否认)两个版本将构建,但具有不同的效果。
另请注意,从C#3开始,您可以像字段一样轻松地声明一个简单的属性:
public int Age { get; set; }
我有一个article about all of this,提供了更多详细信息。
答案 1 :(得分:2)
这是一个空洞的例子。正如您所正确指出的那样,该物业似乎没有做任何事情。
但它可以。例如,SomeClass可以限制Age属性的修改方式(例如,不要将年龄改为-2或823之类的错误值)。此外,SomeClass不需要在内部将age表示为int。年龄可能是计算的结果(比如说从一个人的出生日期减去今天的日期),或者它可以作为另一种数据类型(比如一个字节,长或双)存储在SomeClass中。
答案 2 :(得分:2)
我的意思是,在属性中没有限制逻辑或过滤逻辑,上面的内容与下面的内容有什么不同
这不是你已经或者没有在属性中实现验证逻辑的事实,这里的封装意味着没有人可以直接访问/修改你的私人数据。唯一可用的通道是通过酒店。
使用底部代码,任何人都可以产生异常并造成各种破坏,因为他们可以对数据做任何他们想做的事情。
使用顶部代码作为其编写允许同样的破坏,但在将来的任何时候您都可以在属性中实现限制逻辑,而不必为此类的用户修改API。
答案 3 :(得分:1)
它封装或包装对私有变量age
的更改。私有变量Age
不能由外部呼叫者直接修改,只能通过给定的public
方法修改。它正在设置一个界面,因此将来age
的更改不会破坏呼叫者。对未来的外部呼叫者有利,这就是现在很难看到的原因。
答案 4 :(得分:0)
在您的第一个示例中,SomeClass.Age是一个属性。 “支持”该财产的字段是私有的。在第二个示例中,SomeClass.age是一个公共字段。虽然在许多情况下可能没有区别,但在字段上选择属性使您能够在不更改API或类的“形状”的情况下更改实现。也许你想在财产发生变化时做某事(坚持或通知) - 这对于一个领域是不可能的。
答案 5 :(得分:0)
第一个代码是否提供任何封装?
否(至少你写的特定代码)。
这两段代码几乎相同。与第二个相比,第一个没有提供任何有用的差异(如编写代码)。
使用getter和setter时,可以限制访问私有变量。这可能是封装的一种形式。
即
private int x
public int getInt(String password){
if(password == 'RealPassword'){
return x
}
}