.Net 填坑 接口、父类、子类同名方法的调用

.Net 填坑 接口、父类、子类同名方法的调用

先看代码

1.类与接口定义

    class B : IDisposable, Test
    {
        public void Dispose()
        {
            Console.WriteLine("B Dispose");
        }

        public virtual void Test()
        {
            Console.WriteLine("B Test");
        }
    }

    interface Test
    {
        void Test();
    }

    class C : B, Test
    {

        public new void Test()
        {
            Console.WriteLine("C Test");
        }
    }

2.调用方法

static void Main(string[] args)
    {
        Test c = new C();

        c.Test();

        c = new B();

        c.Test();

        B b = new C();
        b.Test();


        Console.ReadLine();

    }

输出如下:

C Test
B Test
B Test

1.其中第一输出,表示用接口类变量来调用方法时,(类似虚方法调用),会找到变量对应的实际实例(此例子中是类型C的实例对象c),找到实例的类型对象(C类型)的Test方法。
2.第二个输出,同一个原则,实际类型是B类型,所以输出B
3.按照虚方法定义,也应该找到对应实际类型的Test方法来输出,但是输出的是B。原因在于C方法中的New关键字,表示是C类型独有的新的方法,而不是真正的C中的重写父类B中的方法,所以流程是:先找到C类型对象,查找虚方法Test,结果是没找到,然后再去B类中找,找到了,调用B类中的方法。

对应的I代码:

IL_0007: ldloc.0      // c
    IL_0008: callvirt     instance void Program/Test::Test()
    IL_000d: nop

IL_0014: ldloc.0      // c
    IL_0015: callvirt     instance void Program/Test::Test()
    IL_001a: nop

IL_0021: ldloc.1      // b
    IL_0022: callvirt     instance void Program/B::Test()
    IL_0027: nop

可以看到,接口变量调用方法也是虚方法调用的方式

1.将C中的New 改为override后

结果:

C Test
B Test
C Test

第3个流程发生变化,此时C中Test认为是复写了父类B中的虚方法,所以按虚方法的流程,找到实际对象中C的方法进行了调用。

2.去掉C中继承的Test接口

class C : B
    {

        public override void Test()
        {
            Console.WriteLine("C Test");
        }
    }

打印结果:与上面相同,都是走的虚方法调用

3.去掉C中的Test接口,同时修改C中方法为New

    class C : B
    {

        public new void Test()
        {
            Console.WriteLine("C Test");
        }
    }

结果:

B Test
B Test
B Test

此时C中的Test方法,认为是新的只属于C的方法。
1.第一个变为打印B,因为接口走的虚方法调用的原理,去找实际类型C中有没有覆盖的Test方法,没找到(因为New关键字表示C独有的新的方法),然后找到父类B中的虚方法去调用。
2.第2个,找到实例对象B的虚方法,找到了,直接调用
3.第3个,还是B,因为用虚方法调用,去找C中的复写Test虚方法,没找到,从而去找父类B中的,流程与1相同

总结

方法调用,要看调用方法的方式,实例方法与虚方法。
实例方法,直接按变量类型,去找到对应的方法直接调用
实例虚方法,找到变量实际的存储类型,去一层层找到有无复写的虚方法
注意:new与override关键字的区别,特别是new关键字,可以当做是独立的属于类型自身的方法。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值