总结一下使用类继承和多态时,实例化顺序以及方法继承重写中new,virtual、abstract、override的用法和规则:
继承关系:实例化对象时,作用类型范围在最初基类到具体实例对象的类之间(中间包括父类子类,成员访问权限:private、protected、public):
-
子类实例构造器
必须指定拥有父类访问权限的实例构造器
:base(xxx),不写默认父类无参构造器;使用:this(xxx)指定先运行本类的某实例构造器,再由他指定执行的父类实例构造器; -
先实例化基类,再实例化子类,再子类的子类…最后到要实例的类(
实例构造函数执行顺序先父后子…;期间加载时遇到有静态构造器就会先运行静态构造器,再到指定的实例构造器按顺序规则执行,静态构造器只在加载时执行一次,执行过就会跳过
); -
在运行方法时,就运行当前所属类型中的方法:
1). 当遇到隐藏new方法时(实际上C#中使用
签名隐藏
,只要方法名字和参数相同就会隐藏而
new只是消除编译器警告罢了
),说明
子类方法为全新方法与父类不具重写关系
,仍然运行当前所属类型中的方法;
2). 当遇到虚virtual、抽象abstract、继承覆盖override方法时,说明方法具体实现已重写,就运行离具体对象类型关系最近的一个类的
重写方法
。当然关系最近的是自身。
最后例子说明一下:
这里提一下:抽象类无法直接实例化即
不能显式调用构造器(new,反射)
,需要借助子类实例化时,构造函数调用抽象类的构造函数如:base()进行实例化,就是
为继承和重写而生的;抽象实例成员
只能放在抽象类中;静态类只能有
静态成员
(包括构造函数),不能显式调用构造器,初始加载时系统通过构造函数自动创建一个静态对象。
1 public abstract class A
2 {
3 public int x;
4 public A()
5 {
6 x = -1;
7 Console.WriteLine("x={0}", x);
8 Print1();
9 Print2();
10 }
11 public virtual void Print1()
12 {
13 x = 1;
14 Console.WriteLine("x={0}", x);
15 }
16
17 public virtual void Print2()
18 {
19 x = 2;
20 Console.WriteLine("x={0}", x);
21 }
22 }
23
24 public class B : A
25 {
26 public int y;
27 public B()
28 {
29 y = -1;
30 Console.WriteLine("x={0},y={1}", x, y);
31 Print1();
32 Print2();
33 }
34
35 public override void Print1()
36 {
37 x = 3;
38 y = 1;
39 Console.WriteLine("x={0},y={1}", x, y);
40 }
41 //该方法将继承的重新创建,自身及其后子类重写均为这个方法
42 public new virtual void Print2()
43 {
44 x = 4;
45 y = 2;
46 Console.WriteLine("x={0},y={1}", x, y);
47 }
48 }
49 public class C : B
50 {
51 //该方法将继承的重新创建,自身及其后子类继承的均为这个方法
52 public new void Print1()
53 {
54 x = 5;
55 y = 3;
56 Console.WriteLine("x={0},y={1}", x, y);
57 }
58 //该方法重写自父类B,而不是基类A
59 public override void Print2()
60 {
61 x = 4;
62 y = 2;
63 Console.WriteLine("x={0},y={1}", x, y);
64 }
65 }
66 public static class D
67 {
68 public static string _name;
69 static D()
70 {
71 _name = "小明";
72 }
73 }
主程序:
1 static void Main(string[] args)
2 {
3 A c = new C();
4 c.Print1();
5 c.Print2();
6 //静态、抽象类反射不能创建
7 //Type type = typeof(A);
8 //var constructor = type.GetConstructor(Type.EmptyTypes);
9 //Object obj = constructor.Invoke(null);
10 //Console.WriteLine(obj.GetType().Name);
11 //Type type = typeof(D);
12 //var constructor = type.GetConstructor(BindingFlags.Static|BindingFlags.NonPublic,null,Type.EmptyTypes,null);
13 //Object obj = constructor.Invoke(null);
14 //Console.WriteLine(obj.GetType().Name);
15 Console.WriteLine(D._name);
16 Console.ReadKey();
17 }
输出结果:
版权声明:本文为weixin_44033699原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。