zoukankan      html  css  js  c++  java
  • 接口深度剖析(子类没有重新实现)


        interface IFather
        {
            void X();
            void Y();
            void Play();
            void Clear();
        }
       
        class B : IFather
        {
            public   void X()
            {
                Console.WriteLine("B::X()");
            }
            public void Y()
            {
                Console.WriteLine("B::Y()");
            }
            public void Play()
            {
                Console.WriteLine("B::Play()");
            }
            public void Clear()
            {
                Console.WriteLine("B::Clear()");
            }
        }
        class C : B
        {
            public new void Play()
            {//该方法虽然隐藏了基类中的方法,但是并非是虚的
                Console.WriteLine("C::Play()");
            }
            public new void Clear()
            {//该方法虽然隐藏了基类中的方法,但是并非是虚的
                Console.WriteLine("C::Clear()");
            }
        }

      
        class Program
        {
            static void Main(string[] args)
            {
                C c = new C();
                c.X();//cfather::x()
                c.Y();//cfather::y()
                c.Play();//cson::play()
                c.Clear();//cson::clear()
                IFather f = c;
                f.X();//cfather::x()
                f.Y();//cfather::y()
                f.Play();//cfather::play()
                f.Clear();//cfather::clear()
                Console.Read();
            }
        }

     

    这里要深入理解接口中是怎样去找匹配的方法的

    0 先判断接口是否要重新实现,如果不重新实现,则所有的都还是和父类的一样,如果是重新实现,则重新分配

     如果要重新实现则按一下步骤:

    1 在实现接口的类中找本类对应的显示实现(IFather.X())如果找不到

    2 在实现接口的类中找本类对应的virtual方法,如果找不到

    3在实现接口的方法中找本类对应的公有非静态的方法,如果找到则将其虚化(public virtual seleaed)

           并将其放入虚函数表中,如果找不到

    (注意:先找的都是本类的方法,即便是虚表都从子类拷贝过来了,但是还是得区分是本类自己的虚方法还是父类继承过来的虚方法)

    4 到其直接基类中找对应的virtual方法,如果找不到

    4则在该直接基类中找对应的公有非静态的方法,如果找到,本应该将其虚化,但是基类的方法,子类无权虚化,故在

      子类中自动生成一个该方法的显示实现,在显示实现的方法中去调用基类中刚刚找到的方法,如果没找到则继续按这个顺序递归到基类中,知道最后如果找不到则编译错误

    注意:1 被虚化的方法是可以继承,但是不能override的了。

                2在类中,接口表的接口不仅有自己实现的接口,而且所有基类实现的接口都在该类的接口表中。

               3隐藏在虚方法和非虚方法之间也是可以的。非虚方法还是非虚方法,虚方法还是虚方法,在以上例子中,CFather中的play() ,clear() ,x(),y()都被虚化成了public virtual seleaed的,放在了虚方法表中了,在Cson中play() ,clear() ,只是new类以下,而其自身并不是virtual的,故在Cson中play() ,clear() 的两个方法放在了实方法中,如果在Cson中play() ,clear() 都标记成virtual则会新开一个虚方法槽。

    本例分析:编译器看到是隐式实现的接口,就什么也不考虑,使用原来匹配的所有方法,而不重新匹配方法。

  • 相关阅读:
    黑松白鹿
    跨越
    第三年
    Lua windows环境搭建
    Iron man
    水果沙拉
    六周岁
    sqlserver数据库附加报错5120
    [BeiJing2006]狼抓兔子 平面图最小割
    BZOJ2118: 墨墨的等式 思维建图
  • 原文地址:https://www.cnblogs.com/qianyz/p/1839838.html
Copyright © 2011-2022 走看看