public class A
{
public virtual void f1()
{
Console.WriteLine("A");
}
}
public class B:A
{
public override void f1()
{
Console.WriteLine("B");
}
}
public class C:B
{
public override void f1()
{
Console.WriteLine("C");
}
}
public class D:C
{
public virtual void f1()
{
Console.WriteLine("D");
}
}
public class E : D
{
public override void f1()
{
Console.WriteLine("E");
}
}
A aobj = new D();
aobj.f1();
//why output is "C" here
A aobj = new E();
aobj.f1();
//why output is again "C" and not "E"
我很困惑,需要其他人的帮助才能理解,编译器如何决定调用哪个函数?
答案 0 :(得分:2)
在您的示例中,virtual
关键字用于D.f1()
,而不是override
。由于基本方法D.f1()
已经是虚拟的,因此无需将virtual
标记为A.f1()
。
我不确定您是否注意到您当前的代码会引发CS0114
警告:
CS0114: 'D.f1()' hides inherited member 'C.f1()'.
To make the current member override that implementation, add the override keyword.
Otherwise add the new keyword.
将class D
更改为以下内容可以解决问题:
public class D:C
{
public override void f1() // Notice use of 'override' instead of 'virtual'
{
Console.WriteLine("D");
}
}
通过上述更改,将返回预期输出:
D
E
看看这两个问题,讨论一个非常类似的问题:
编辑:行为背后的基本原理
aobj
是class A
的一个实例。因此,从基类A向上工作以识别调用哪个版本的f1()
。 最高覆盖方法为C.f1()
因此将被调用。使用virtual
在D类中打破了覆盖的层次结构,因此在使用D.f1()
的实例时不会调用E.f1()
和class A
。
答案 1 :(得分:0)
在你的D类中,你再次使用虚拟,你需要使用覆盖,它隐藏了c.F1()的继承
public class D:C
{
public virtual void f1()
{
Console.WriteLine("D");
}
}