10.1 成员的定义
在类一种,也提供该类所有成员的定义——字段、属性、方法。所有成员都有自己的访问级别(可以对比类的访问级别):
public——成员可以由任意代码访问。
private——成员只能由类中的代码访问(如果使用任何关键字即没有定义访问级别,默认使用这个关键字)
internal——成员只能由定义他的程序集(项目)内部的代码访问。
protected——成员只能由类或派生类中的代码访问。(受保护的)
其中internal、protected两个关键字可以结合使用,即protected internal成员。它只能由项目(程序集)中的派生类的代码访问。
也可以用关键字static来声明字段、属性、方法,这表示他们是类的静态成员,而不是对象实例的成员。
类的访问级别在第九章 P178
10.1.1 定义字段
1、与定义变量的格式和之前介绍的修饰符来定义字段。
<访问级别> <类型><字段名>;
2、公共字段用PascalCasing形式来明明。私有字段没有推荐的名称大小写模式,他们通常使用camelCasing来命名。
3、字段也可以用关键字readonly,表示字段只能在执行构造函数过程中赋值或由初始化赋值语句赋值。
4、静态字段只能由定义它的类来访问而不能通过这个类的对象实例。const关键字用来创造常量,常量也是静态的,不需要使用静态修饰符static。
10.1.2 定义方法
1、方法使用标准函数格式、可访问性及可选的static修饰符来声明。
2、与公共字段一样,公共方法也采用PascalCasing形式来命名。
3、如果使用static关键字,该方法就只能通过类来访问,不能通过对象实例来访问。
4、也可以用下述关键字来定义方法:
virtual——方法可以重写。(把方法定义成虚拟的)
abstract——方法必须在非抽象的派生类中重写(只能用于抽象类)
override——方法重写了一个基类方法(如果方法被重写,就使用这个关键字)
extern——方法定义在其他地方
与override相关的一个关键字是sealed(密封),如果在一个派生类中,重写某个基类方法时使用sealed关键字,则该派生类的派生类中——如果存在的话——不能再次重写该方法。
10.1.3 定义属性
1、属性有两个类似函数的块,一个用于获取属性值(get),一个用于设置属性值(set)。这两个块成为函数的访问器。可以控制属性的访问级别。忽略其中一个块意味着取消该块的功能,如忽略set块意味着不能设置属性值,那么该属性就是只读属性。
2、还可以在块中包含访问修饰符,如将get块变为公共的,将set块变为受保护的。
3、至少包含一个块属性值才是有效的。
4、属性的基本结构包括标准的可访问修饰符(public、private等),后跟类名、属性名和块,eg:
public int MyIntProp
{
get
{
return 2;
}
set
{
}
}
5、公共属性也以PascalCasing方式来命名。
6、get块必须有属性类型返回值,简单属性一般与私有字段相关联,以控制对这个字段的访问,此时get块可以返回这个字段的值。因为该字段是私有的所以外部代码不能直接访问,必须通过属性来访问该字段。set函数采用类似方法把一个值赋值给字段。使用value表示用户提供的属性值。
7、属性的访问器可以使用virtual、override、abstract关键字(但这几个关键字不能用于字段),这样属性的访问器就有自己的可访问性了。
8、只有类或派生类中的代码才能使用set访问器。访问器可以使用的访问修饰符取决于属性的可访问性,访问器的可访问性不能高于它所属的属性。例:私有属性不能包含任何可访问修饰符,公共属性则可以对其访问器使用所有的可访问修饰符。
10.1.4 在类图中添加成员
这是通过VS操作,可以方便的添加成员由.NET自动生成相关代码。
10.2 类成员的其他主题
10.2.1 隐藏基类方法
隐藏基类方法和重写基类方法的区别。
隐藏基类方法通过在派生类中使用new关键字显式的表明意图。当然,如果直接不做显式的表明,直接在派生类中重定义该方法的话也会隐藏基类方法,但会产生一个隐藏了一个基类成员的警告——系统不知道你是不是有意隐藏它。
在派生类中重写方法会替换基类方法,此时实例化派生类,然后将派生类赋值给基类,基类的方法会被派生类替换,重写方法要求基类方法必须是虚拟的;而隐藏方法则对基类方法的是否虚拟没有任何要求,只需在派生类的方法中使用new关键字。此时尽管隐藏了基类方法,但仍然可以通过基类访问它且不会被派生类的方法替换。
10.2.2 调用重写或隐藏的基类方法
俩关键字 base、this
1、base:
在派生类中实现基类的虚拟方法时,若只需要调用基类的方法,可以直接在派生类方法的结构体中base.FuctionName();
base使用的是对象实力,所以在静态成员中使用它会产生错误。(静态成员不能实例化)
2、this:
与base一样,this可以用在类成员内部,且关键字也引用对象实例。只是this引用的是当前的对象实例。
1) this关键字最常见功能是把当前对象实例的引用传递给一个方法。如:
public void doSomething()
{
MyTargetClass myObj=new MytargetClass();
myObj.DoSomethingWith(this);
}
其中被实例化的MyTargetClass实例myObj有一个DoSomethingWith()方法,该方法带有一个参数,其类型与包含上述方法的类兼容。这个参数类型可以是类的类型、由这个类继承的类类型,或者由这个类或System.Object实现的一个接口。
2) this关键字的另外一个常见用法是限定局部类型成员。如:
属性中返回私有字段的值。
{
private int someData;
public int SomeData
{
get
{
return this.someData;
}
}
}
10.2.3 嵌套类型定义
除了在名称空间中定义类型(如类)之外,还可以在其他类中定义他们。如果这么做,就可以在定义中使用各种访问修饰符,而不仅仅是public和internal,也可以使用new关键字来隐藏继承于基类的类型定义。
若要在包含类外部实例化类中的嵌套类,就必须限定名称。MyClass.MyNewClass myObj=new MyClass.MyNewClass;
但如果嵌套的类声明为私有,就不能这么做。这个功能主要用来定义对于其包含类来说是私有的类,这样名称空间中的其他成员就不能访问它。使用该功能的另一个原因是嵌套类可以访问其包含类的私有和受保护的成员。
例如,包含类中定义了一个私有字段state和与之对应的只读属性State,嵌套类中的方法可以访问这个字段。