标签:add 并且 name com 经历 控制 结果 type inter
namespace ConsoleApp1 { public interface It { void PI(); } public class A : It { private int _type = 0; public int Type = 0; public A a; public A(int type) { Type = _type = type; } public virtual void P() { Console.WriteLine("这是A的PP!"); } public virtual void PI() { Console.WriteLine("这是A的PI!"); } public void Dispatch() { Console.WriteLine("这里是指令分派的接口哦!"); a.P(); switch (_type) { case 1: (a as B).PP(); break; case 2: (a as C).PP(); (a as B).PP(); break; } } } public class B : A { public B(int type) : base(type) { a = this; } public override void P() { Console.WriteLine("这是B的PP!"); } public override void PI() { Console.WriteLine("这是B的PI!"); } public void PP() { Console.WriteLine("这是转发B的PP!"); } } public class C : B { public C(int type) : base(type) { a = this; } public override void P() { Console.WriteLine("这是C的PP!"); } public override void PI() { Console.WriteLine("这是C的PI!"); } public new void PP() { Console.WriteLine("这是转发C的PP!"); } } } namespace ConsoleApp1 { class Program { static void Main(string[] args) { _dictClass.Add(0, new A(0)); _dictClass.Add(1, new B(1)); _dictClass.Add(2, new C(2)); _dictInterface.Add(0, new A(0)); _dictInterface.Add(1, new B(1)); _dictInterface.Add(2, new C(2)); _dictClass[0].P(); Console.WriteLine(_dictClass[0].Type); _dictClass[1].P(); Console.WriteLine(_dictClass[1].Type); _dictClass[2].P(); Console.WriteLine(_dictClass[2].Type); Console.WriteLine(); Console.WriteLine("ding------------------------------ding"); Console.WriteLine(); _dictClass[1].Dispatch(); _dictClass[2].Dispatch(); Console.WriteLine(); Console.WriteLine("ding------------------------------ding"); Console.WriteLine(); _dictInterface[0].PI(); _dictInterface[1].PI(); _dictInterface[2].PI(); } private static Dictionary<int, It> _dictInterface = new Dictionary<int, It>(); private static Dictionary<int, A> _dictClass = new Dictionary<int, A>(); } }
代码并没有什么明显的变化,只是原来的C继承A现在改成了继承B,先看看输出
首先分析一下,
B中的P方法overrideA,C又进行了override,那么C究竟是override的A还是B呢?这个稍后再说。
第一段输出,参数和方法P与之前说的是一样的,这个就不再重复了
看第二段,这里我在构造BC实例的时候,把实例本身也保存在了A中,并且使用Dispatch来进行了调用控制
case1,也就是作为B的实例本身来调用PP,不同的是PP并不是虚函数子类也没有override,因此,实例b只能打印B的,而实例c在内部又构造了一个新的PP(),因此不仅可以调用父类B中的方法也能调用自己的方法。
接口的话继承override方式也是一样的。
然后我们看究竟C里面的Poverride的究竟是A还是B中的方法。
namespace ConsoleApp1 { public interface It { void PI(); } public class A : It { private int _type = 0; public int Type = 0; public A a; public A(int type) { Type = _type = type; } public virtual void TA() { Console.WriteLine("这是A的TA!"); } public virtual void P() { Console.WriteLine("这是A的PP!"); } public virtual void PI() { Console.WriteLine("这是A的PI!"); } public void Dispatch() { Console.WriteLine("这里是指令分派的接口哦!"); a.P(); switch (_type) { case 1: (a as B).PP(); break; case 2: (a as C).PP(); (a as B).PP(); break; } } } public class B : A { public B(int type) : base(type) { a = this; } public override void TA() { base.TA(); Console.WriteLine("这是B的TA!"); } public override void P() { Console.WriteLine("这是B的PP!"); } public override void PI() { Console.WriteLine("这是B的PI!"); } public void PP() { Console.WriteLine("这是转发B的PP!"); } } public class C : B { public C(int type) : base(type) { a = this; } public override void TA() { base.TA(); Console.WriteLine("这是C的TA!"); } public override void P() { Console.WriteLine("这是C的PP!"); } public override void PI() { Console.WriteLine("这是C的PI!"); } public new void PP() { Console.WriteLine("这是转发C的PP!"); } } } namespace ConsoleApp1 { class Program { static void Main(string[] args) { //_dictClass.Add(0, new A(0)); //_dictClass.Add(1, new B(1)); _dictClass.Add(2, new C(2)); _dictClass[2].TA(); //_dictInterface.Add(0, new A(0)); //_dictInterface.Add(1, new B(1)); //_dictInterface.Add(2, new C(2)); //_dictClass[0].P(); //Console.WriteLine(_dictClass[0].Type); //_dictClass[1].P(); //Console.WriteLine(_dictClass[1].Type); //_dictClass[2].P(); //Console.WriteLine(_dictClass[2].Type); //Console.WriteLine(); //Console.WriteLine("ding------------------------------ding"); //Console.WriteLine(); //_dictClass[1].Dispatch(); //_dictClass[2].Dispatch(); //Console.WriteLine(); //Console.WriteLine("ding------------------------------ding"); //Console.WriteLine(); //_dictInterface[0].PI(); //_dictInterface[1].PI(); //_dictInterface[2].PI(); } private static Dictionary<int, It> _dictInterface = new Dictionary<int, It>(); private static Dictionary<int, A> _dictClass = new Dictionary<int, A>(); } }
嫌代码长的话不看也行,这段代码只是在ABC中加了个TA方法,用来判断执行顺序的,来看结果:
看起来在调用C中的TA()之前先向上级索引找到了B中的TA(),然后B中override了A的TA()继续向上寻找,最后打印结果如上,
先不急,我们再看看假如B中没有overrideTA()的话结果如何,
看到了没,并没有经历B,也就是说override函数TA()在索引父类时并没有找到它的模板,
因此在笔者理解看来,子类override方法应该是直接override的直系父类,如果直系父类中没有才会向更上级索引,也就是说如果父亲有这个可以被override的方法,那么override它,不然就去爷爷那里去找,或者再往上到老祖宗那里找,当找打距离最近的一个时override它。
最后,要提醒的是,实例是new出来后才能用的,比如,A b= new B()
b是无法调用子类C的override函数的,这是因为b是C的爸爸实例出来的,或者说B是一个中箱子,C是一个大箱子,你可以把B压缩,但里面的东西不会少,但是你把他扩大却不能增加里面的东西。
接口和类在这一方面上的特性是相同的。
标签:add 并且 name com 经历 控制 结果 type inter
原文地址:https://www.cnblogs.com/fairy-blonde/p/11567105.html