首页 新闻 会员 周边

C#中的Override

0
悬赏园豆:100 [待解决问题]

C#中基类以Virtual或Abstract修饰的方法,子类继承时,可以以Override修饰重写其实现。但是多层继承时,子类Override重写的是父类的Override方法还是基类的Virtual或Abstract方法???如下图,B类中的Output方法重写的是A类中的Output方法还是Word类中的Output方法???

C#
--澈--的主页 --澈-- | 初学一级 | 园豆:102
提问于:2024-03-06 21:49
< >
分享
所有回答(4)
0

当然是父类的,不信你把 A 的方法设置成 sealed 看看 B 还能不能继承

拓拓 | 园豆:1050 (小虾三级) | 2024-03-07 10:11
0

A的。

按照现有的代码,虚方法表的指向是这样的:

 所以,会有以下执行结果:

无论静态类型是Word还是A,Output方法总会输出B

 

但是,如果我们在B中不进行Override,那么方法表的指向就是这样的:

 所以,执行结果就是这样的:

无论静态类型是Word还是A,都会输出A类型的Output结果

talentzemin | 园豆:761 (小虾三级) | 2024-03-07 10:18
0

抽象和虚拟使用虚方法表在运行时查找方法,运行时会从对象实际类型的虚方法表开始逐步向祖先类型的虚方法表查找,直到找到匹配的方法,方法定义中可以从base访问基类方法,同样也是从父类开始逐步向上查找直到找到。因此只要重写,方法就属于自己,不重写,方法就属于最接近的基类。子类不重写就可以调用只是因为查找方法会回溯到祖先类型,编译器会确保方法一定在某个祖先类存在定义,所以能通过编译。也因此重写方法支持隔代重写而不用关心被重写的方法最后一次是被谁重写的。

coredx | 园豆:678 (小虾三级) | 2024-04-12 16:48
0

其实不存在你所问的问题。

通俗地讲,在逻辑上只有类和实例两种东西。同时,类A和类B实际是两个独立的类。

当你用 类A的实例调用方法 Output,则输出字母A;当你用 类B的实例调用方法 Output,则输出字母B。

A a = new A(); a.Output();//类A的实例调用方法 Output,则输出字母A;
B b = new B(); b.Output();//类B的实例调用方法 Output,则输出字母B;
A a = new B(); a.Output();//类B的实例调用方法 Output,则输出字母B;

需要判断实际是哪个类的实例在调用方法。

假如:你有类C,继承自A,里面啥方法都没有写,代码如下:
public class C: A { }
那么,C c=new C(); c.Output();//实例c,调用的方法就是A 的 Output方法,则输出字母A;

你有类D,继承自C,里面override Output方法,代码如下:
public class D: C { public override void Output(){ } }
那么,C d=new D(); d.Output();//实例d,调用的方法就是D 的 Output方法,方法啥也没做;

总结起来就是:A,B,C,D 是独立的类,都有各自 Output 方法,给自己的实例使用。如果类中没 override Output,就逐个往“祖上”找,直到找到。

override关键字,并不表示它要重写谁的方法,而是标识这个方法名可以被子类、孙类使用(参数、返回都一样)。每个类其实还是独立的。只是让开发人员少写代码。或者 之前写的代码 可以复用。

误会馋 | 园豆:242 (菜鸟二级) | 2024-04-19 16:03
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册