原文链接
版权声明:本文为CSDN博主「Altair_Alpha_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
正文
在这节,我们来介绍属性(Properties)。你可以把属性理解为一个“智能”的变量。在外部,你可以像访问变量一样访问属性。属性的智能体现在两方面:
- 一是可以控制变量的 访问权限,
- 二是可以对变量的读写过程做 自定义的控制。
如何创建一个属性
属性本身不包含一个变量,需要与一个声明的变量相联系。属性内有两个域(访问器):get 和 set。
get就是外部读取这个属性时会执行的部分,所以需要一个与声明的类型相对应的返回值;set:是外部修改这个属性时会执行的部分,关键字value会存储外部传入的值。
所以最基本的,我们会这样写一个属性:
public bool isGameOver;
public bool IsGameOver
{
get
{
return isGameOver;
}
set
{
isGameOver = value;
}
}
Tips:属性名应该以 大写字母开头
如上所示,我们先创建了一个 isGameOver 变量,然后创建了对应的 IsGameOver 属性。
在 get 访问器中,我们返回了 isGameOver 的值;
在 set 访问器中,我们将外部传入的值 value 赋给了 isGameOver。
显然,现在我们在外部访问 isGameOver 变量和 IsGameOver 属性的效果是完全一样的。在外部看来,我们的属性是这样子的:
属性的智能之处
在面向对象的程序设计中,封装是非常重要的一种思想。我们会尽量使用 private 修饰符来保护无需对类外暴露的变量。但如果我们想创建一个 对外只能读取不能修改的变量 ,怎么做?显然这个变量不能是 public 修饰的,但 private 又会使这个变量对外不可见。
在属性中,变量的访问被分为了两个域: get 和 set。那么我们只需要去掉 set 访问器,就可以让它关联的 private 变量实质上对外变为只读状态。但是这样会 导致 我们在类内也无法对其进行修改,所以 要使用 private set,或者 protected set,如果希望在继承类中也可修改的话。
另一方面,在 get 和 set 中我们完全可以像在一个方法中自由操作(实际上,属性的实现就是利用了方法),所以可以在其中加入一些其它逻辑。但是也 不宜 过于复杂,因为外部的访问有很大的不确定性,可能导致一些难以预料的错误发生。
对于上面的 isGameOver 进行一些改写:
private bool isGameOver;
public bool IsGameOver
{
get
{
return isGameOver;
}
private set
{
isGameOver = value;
if (isGameOver == true)
{
Debug.Log("Oops, the game is over");
}
}
}
我们之前用到过的
Time.deltaTime就是一个只读属性。
自动属性
如果不需要在 get 和 set 中做额外的操作,还可以使用 自动属性。在上例中,我们先声明了 isGameOver 变量,再声明 IsGameOver 属性,看起来有些繁琐。实际上,有了属性,我们已经不需要直接访问原来的变量了。利用自动属性,我们只需要声明属性,编译器会帮我们 自动生成 一个 隐藏的变量,格式如下:
可以看到效果和上例是完全一样的。