也谈继承
1. 子类隐藏了父类的方法
当子类与父类拥有完全一样的方法时,称子类隐藏(Hide)了父类的同名方法。
1 namespace Test {
2 public class Parent {
3 public void HideF() {
4 Console.WriteLine("Parent.HideF()");
5 }
6 }
7 public class Child : Parent {
8 public void HideF() {
9 Console.WriteLine("Child.HideF()");
10 }
11 }
12
13 class Program {
14 static void Main(string[] args) {
15 Child c = new Child();
16 c.HideF();//输出Child.HideF()
17 Parent p1 = new Parent();
18 p1.HideF();//输出Parent.HideF()
19 Parent p2 = new Child();
20 p2.HideF();//输出Parent.HideF()
21
22 Console.ReadKey();
23 }
24 }
2 public class Parent {
3 public void HideF() {
4 Console.WriteLine("Parent.HideF()");
5 }
6 }
7 public class Child : Parent {
8 public void HideF() {
9 Console.WriteLine("Child.HideF()");
10 }
11 }
12
13 class Program {
14 static void Main(string[] args) {
15 Child c = new Child();
16 c.HideF();//输出Child.HideF()
17 Parent p1 = new Parent();
18 p1.HideF();//输出Parent.HideF()
19 Parent p2 = new Child();
20 p2.HideF();//输出Parent.HideF()
21
22 Console.ReadKey();
23 }
24 }
25 }
结论:当分别位于父类和子类的两个方法完全一样时,调用哪个方法由对象变量的编译时类型决定。
2. 方法重写和虚方法调用
在父类同名方法前加关键字virtual,表明这是一个虚方法,子类可以重写此方法。于此同时,需要在子类同名方法前加关键字override,表明对父类同名方法进行了重写。
1 namespace Test {
2 class Parent {
3 public virtual void HideF() {
4 Console.WriteLine("Parent.HideF()");
5 }
6 }
7 class Child : Parent {
8 public override void HideF() {
9 Console.WriteLine("Child.HideF()");
10 }
11 }
12
13 class Program {
14 static void Main(string[] args) {
15 Child c = new Child();
16 c.HideF();//输出Child.HideF()
17 Parent p1 = new Parent();
18 p1.HideF();//输出Parent.HideF()
19 Parent p2 = new Child();
20 p2.HideF();//输出Child.HideF()
21
22 Console.ReadKey();
23 }
24 }
2 class Parent {
3 public virtual void HideF() {
4 Console.WriteLine("Parent.HideF()");
5 }
6 }
7 class Child : Parent {
8 public override void HideF() {
9 Console.WriteLine("Child.HideF()");
10 }
11 }
12
13 class Program {
14 static void Main(string[] args) {
15 Child c = new Child();
16 c.HideF();//输出Child.HideF()
17 Parent p1 = new Parent();
18 p1.HideF();//输出Parent.HideF()
19 Parent p2 = new Child();
20 p2.HideF();//输出Child.HideF()
21
22 Console.ReadKey();
23 }
24 }
25 }
结论:这一示例表明将父类方法定义为虚方法,子类重写同名方法后,通过父类变量调用此方法,到底是调用父类还是子类的方法,由父类变量引用的真实对象类型决定,而与父类变量无关。
3. 子类父类同名字段的情况
前面介绍的都是访问方法的,如果子类字段和父类字段同名,那又会出现什么情况?
1 namespace Test {
2 class Parent {
3 public int i = 100;
4 }
5 class Child : Parent {
6 public int i = 200;
7 }
8
9 class Program {
10 static void Main(string[] args) {
11 Child c = new Child();
12 Console.WriteLine(c.i);//输º?出?200
13 Parent p1 = new Parent();
14 Console.WriteLine(p1.i); ;//输º?出?100
15 Parent p2 = new Child();
16 Console.WriteLine(p2.i); ;//输º?出?100
17
18 Console.ReadKey();
19 }
20 }
21 }
3 public int i = 100;
4 }
5 class Child : Parent {
6 public int i = 200;
7 }
8
9 class Program {
10 static void Main(string[] args) {
11 Child c = new Child();
12 Console.WriteLine(c.i);//输º?出?200
13 Parent p1 = new Parent();
14 Console.WriteLine(p1.i); ;//输º?出?100
15 Parent p2 = new Child();
16 Console.WriteLine(p2.i); ;//输º?出?100
17
18 Console.ReadKey();
19 }
20 }
21 }
结论:如果子类与父类有相同名字的字段,到底使用哪个字段,由对象变量编译时的类型决定,而与程序运行时对象变量引用的真实对象类型无关。