7.1 类成员
表 7-1 类成员的类型
数据成员(保存数据) | 函数成员(执行代码) |
---|---|
字段、常量 | 方法、属性、构造函数、析构函数、运算符、索引、事件 |
7.2 成员修饰符的顺序
[特性] [修饰符] 核心声明
public static int Val; // 例子
7.3 实例类成员
略
7.4 静态字段
class Women
{
public string name; // 实例字段
static public string gender = "female"; // 静态字段
}
静态字段被类的所有实例共享,所有实例都访问同一内存位置。
7.5 从类的外部访问静态成员
- 可以直接使用类名,如
Women.gender
- 使用
using static
声明,详见第 22 章。
静态成员的生存期:即使类没有实例,也存在静态成员,并且可以访问。
7.6 静态函数成员
class Women
{
static public string gender = "female"; // 静态字段
static public void PrintGender() // 静态函数成员
{
Console.WriteLine("Gender: {0}", gender);
}
}
- 即使没有类的实例,仍然可以调用静态方法;
- 静态函数成员不能访问实例成员,但能访问其他静态成员。
7.7 其他静态成员类型
常量和索引器不能被声明为static
。
7.8 成员常量
与局部常量类似:
- 用于初始化成员常量的值在编译时必须是可计算的;
- 不能在声明后给它赋值。
7.9 常量与静态量
成员常量表现得像静态量——即使没有类的实例也可以使用。但是常量没有自己的存储位置。
7.10 属性
class Student
{
int grade;
public int Grade
{
set { grade = (value <= 100 ? value : 100); }
get { return grade; }
}
}
属性是一组称为访问器的方法:
set
访问器为属性赋值;get
访问器从属性获得值。
set
访问器总是:
- 拥有一个单独的、隐式的形参
value
,与属性类型相同; - 拥有返回类型
void
get
访问器总是:
- 没有参数;
- 拥有一个与属性类型相同的返回类型。(所以必须包含一条
return
语句)
只有get
访问器的属性称为只读属性,只有set
访问器的属性称为只写属性。
7.10.9 自动实现属性
class Student
{
public int Grade
{
set; get;
}
}
- 不用声明后备字段——编译器根据属性类型分配存储;
- 不能有访问器的方法体,直接跟分号即可。
7.10.10 静态属性
属性可以被声明成static
,特性和所有静态成员一样。
7.11 实例构造函数
class Student
{
string name;
int grade;
public Student(string inputName, int inputGrade)
{
name = inputName;
grade = inputGrade;
}
}
- 构造函数名称和类名相同;
- 不能有返回值;
- 可以带参数;
- 可以被重载。
7.11.2 默认构造函数
如果类的声明中没有显式地提供实例构造函数,编译器会提供一个隐式的默认构造函数:
- 没有参数
- 方法体为空。
如果类的声明中有实例构造函数,则编译器不会定义默认构造函数。
7.12 静态构造函数
class Student
{
static public string race;
static Student()
{
race = "Human";
}
}
构造函数也可以声明为static
,通常用来初始化类的静态字段。注意:
- 类只能有一个静态构造函数;
- 不能带参数;
- 不能有访问修饰符,例如
public
; - 不能被显式调用,系统会在实例被创建之前或者静态成员被引用之前自动调用它们。
7.13 对象初始化语句
new Typename { FieldOrProp = InitExpr, FieldOrProp = InitExpr, ...}
new Typename(ArgList) { FieldOrProp = InitExpr, FieldOrProp = InitExpr, ...}
- 创建对象的代码必须能访问到要初始化的字段和属性;
- 初始化发生在构造方法执行之后。
7.14 析构函数
详见第 27 章。
7.15 readonly
修饰符
用于修饰字段,类似于const
,但是存在以下区别:
const
字段只能在声明语句中初始化,而readonly
字段可以在声明语句或者构造函数中设置;const
字段的值必须可在编译时决定,而readonly
字段的值可以在运行时决定;const
的行为总是静态的(在内存中没有存储位置),而readonly
字段可以是实例字段或者是静态字段,在内存中有存储位置。
7.16 this
关键字
this
是对当前实例的引用,只能用于实例构造函数、实例方法、属性和索引器的实例访问器。目的是:
- 区分类的成员和其他同名参数或变量;
- 作为调用方法的实参。
7.17 索引器
using System;
namespace Test
{
class Monster
{
int hp, mp, atk, def;
public int this [int index]
{
set
{
switch (index)
{
case 0: hp = value;
break;
case 1: mp = value;
break;
case 2: atk = value;
break;
case 3: def = value;
break;
default:
throw new ArgumentOutOfRangeException("index");
}
}
get
{
switch (index)
{
case 0: return hp;
case 1: return mp;
case 2: return atk;
case 3: return def;
default:
throw new ArgumentOutOfRangeException("index");
}
}
}
}
class Program
{
static void Main()
{
Monster boss = new Monster();
for (int i = 0; i < 4; ++i)
boss[i] = 1000 + 100 * i;
for (int i = 0; i < 4; ++i)
Console.WriteLine("Value of Field {0}: {1}", i, boss[i]);
}
}
}
可以认为索引器是为类的多个数据成员提供get
和set
访问的属性,并且通过索引器建立索引到数据成员之间的映射,注意:
- 索引可以是任何类型,可以有多个参数;
get
和set
可以只有一个,或者两个都有;- 不能被声明成
static
; - 可以重载,必须用不同的参数列表重载。
7.18 访问器的访问修饰符
访问器指get
和set
,访问修饰符指public
,protected internal
,protected
,internal
。
- 仅当属性或索引器同时有
get
和set
时,才能为其中的一个访问器添加修饰符; - 访问器的访问修饰符限制必须比属性或索引器的访问级别更严格(限制性层次关系见 P127 图 7-19)。
7.19 分部类和分部类型
略
7.20 分布方法
略