C#继承override与接口的引入(三)

2021-02-02 06:13

阅读:724

标签: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 Dictionaryint, It> _dictInterface = new Dictionaryint, It>();
        private static Dictionaryint, A> _dictClass = new Dictionaryint, 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 Dictionaryint, It> _dictInterface = new Dictionaryint, It>();
        private static Dictionaryint, A> _dictClass = new Dictionaryint, 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压缩,但里面的东西不会少,但是你把他扩大却不能增加里面的东西。

接口和类在这一方面上的特性是相同的。

 

C#继承override与接口的引入(三)

标签:add   并且   name   com   经历   控制   结果   type   inter   

原文地址:https://www.cnblogs.com/fairy-blonde/p/11567105.html


评论


亲,登录后才可以留言!