我有简单的三个类:
class A
{
public virtual void Write()
{
Console.Write("A");
}
}
class B:A
{
public override void Write()
{
Console.Write("B");
}
}
class C : B
{
public new void Write()
{
Console.Write("C");
}
}
我正在创建对象并调用其方法:
A a = new A();
a.Write();
A b = new C();
b.Write();
C c = new C();
c.Write();
输出将是: ABC
我不明白的是为什么这些代码会产生B
?:
A b = new C();
b.Write();
我认为应该C
。但是,我测试了很多次,并且始终如此B
。
我知道会A b = new C()
创建C的新对象类型。因此输出应为C。还是在不使用强制转换的情况下调用覆盖方法是一种特殊的行为?
为什么会发生?由于我们没有使用任何对B
类的引用。
如果您使用它会工作 ((C)b).Write();
使用new
关键字,您不会覆盖Write
C的方法,而是创建仅为C定义的新方法。因此,对于您的C,您实际上有2个带有方法名称的方法Write
。
A c = new C();
c.Write(); //Output "B", you're calling the overridden method
((C)c).Write(); //Output "C", you're calling the method defined on C
//or
(c as C).Write();
将c定义为时,也会发生相同的情况C
:
C c = new C();
c.Write(); //Output "C"
((A)c).Write(); //Output "B"
在第一个示例中,您正在调用C上定义的新方法。在第二行中,您Write
从A中调用了该方法,该方法被B覆盖,因此输出"B"
。
编辑:(更多解释)
变量c
的类型为A,因此您的编译器知道“ c是A的实例”,但实际上它不是派生类型。当您Write
在其上调用方法时,它将调用在A(由B覆盖)上定义的方法。基类A不了解在C上定义的新方法(即new
会创建一个新方法),因此,除非将其强制转换为C以使编译器知道c
基方法的实际派生类型,否则它不知道类将被调用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句