屏蔽基类的成员

派生类不能删除它继承的成员但是可以用与基类成员名称相同的成员来屏蔽基类成员。
要让编译器知道你是故意屏蔽,可使用new操作符。
也可以屏蔽静态成员。

1
2
3
4
5
6
7
8
9
10
11
12
class Father {
public string name = "爸爸";
public void MakeMoney() {
Console.WriteLine("我可以赚钱");
}
}
class Son : Father {
new public string name = "儿子";
new public void MakeMoney() {
Console.WriteLine("我也可以赚钱");
}
}

基类访问

如果需要访问被隐藏的继承成员,可使用基类访问表达式:base.

1
Console.WriteLine(base.name);

基类引用

可以声明基类变量引用子类实例,但是产生的变量仅能访问到基类身上的成员。

1
Father father = new Son();

构造函数的执行

初始化实例成员——>调用基类构造函数——>执行实例构造函数方法体。
注意:强烈反对在构造函数中调用虚方法。在执行基类的构造函数时,基类的虚方法会调用派生类的复写方法,但这是在执行派生类的构造函数方法体之前。因此,调用会在派生类完全初始化之前传递到派生类。

初始化构造函数

可以指定用某个基类的构造函数来初始化子类的构造函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Program {
static void Main(string[] args) {
Man man1 = new Man();
Console.WriteLine(man1.Height);
Man man2 = new Man(180);
Console.WriteLine(man2.Height);
}
}
class Human {
public int Height;
public Human(int height) {
this.Height = height;
}
public Human() {
this.Height = 165;
}
}
class Man : Human {
public Man() :base() {}
public Man(int height) : base(height) {}
}

还可以让构造过程使用当前类中其他的构造函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Program {
static void Main(string[] args) {
Human human = new Human(75,180);
Console.WriteLine($"身高{human.Height},体重{human.Weight}");
}
}
class Human {
public int Height;
public int Weight;
private Human(int height) {
this.Height = height;
}
public Human(int weight,int height) :this(height){
this.Weight = weight;
}
}

如果一个类有好几个构造函数,并且它们都需要在对象构造的过程开始时执行公共的代码,可以把公共代码抽取出来作为一个构造函数。
readonly字段只能在构造函数中初始化,但是readonly属性不受这个限制。