C# virtual关键字调用方法的大多数派生定义吗?
我正在读这篇文章 我读到:“.当对一个对象调用虚方法时,就会调用该方法的最派生版本” 但当我执行以下代码时:C# virtual关键字调用方法的大多数派生定义吗?,c#,.net,oop,polymorphism,C#,.net,Oop,Polymorphism,我正在读这篇文章 我读到:“.当对一个对象调用虚方法时,就会调用该方法的最派生版本” 但当我执行以下代码时: class A { public virtual void print() { Console.WriteLine("A called"); Console.Read(); } } class B :A { public override void print() { Console.WriteL
class A
{
public virtual void print()
{
Console.WriteLine("A called");
Console.Read();
}
}
class B :A
{
public override void print()
{
Console.WriteLine("B called");
Console.Read();
}
}
class C : B
{
public override void print()
{
Console.WriteLine("C called");
Console.Read();
}
}
static void Main(string[] args)
{
B b = new B();
b.print(); it prints B?
}
它打印B。如果上述说法属实,不应该是“C”吗?
我错过了什么?在此上下文中,“最派生的”是什么意思?它将从调用它的实例的类型调用方法,您使用类
B
的实例调用它,因此将调用B
的实现,若您使用的是类C
的实例,那个么将调用C
类的重写实现
例如:
class B :A
{
public override void print()
{
Console.WriteLine("B called");
Console.Read();
}
public virtual void printfromB()
{
Console.WriteLine("printfromB in B called");
Console.Read();
}
}
class C : B
{
public override void print()
{
Console.WriteLine("C called");
Console.Read();
}
public override void printfromB()
{
Console.WriteLine("printfromB in C called");
Console.Read();
}
}
现在如果你这样称呼它:
static void Main(string[] args)
{
A a = new C();
a.print(); // it prints C (most derived implementation called)
B b = new C();
b.printfromB(); // it prints "printfromB in C called"
}
当实际类型为
B
时,不可能调用C
最初的“最衍生”术语可通过以下方式理解:
A data = new C();
data.print();
A a = new C();
a. print(); // Should call the method on class C, since base class has reference to to the instance of C.
即使编译器将数据
视为A
,也会调用最派生的版本(不是A.print
或B.print
,而是C.print
)(这是因为该方法是虚拟的
)
见我想你对答案中的术语感到困惑了 这里有两件事
A a = new B();
a. print(); // this will invoke the method on the class B,
// since instance of class A has reference to instance of B.
如果您执行以下操作:
A data = new C();
data.print();
A a = new C();
a. print(); // Should call the method on class C, since base class has reference to to the instance of C.
同样,更直观的表述方式是:
A a = new A();
a.print(); // this will call the method print in class A irrespective of whether this method was overriden in one of the derived classes.
这是动态多态性的前提,其中,客户机可以调用
无需知道A是否引用了B或C。客户端代码中的行为会动态变化
class A
{
public virtual void print()
{
Console.WriteLine("A called");
Console.Read();
}
}
class B :A
{
public override void print()
{
Console.WriteLine("B called");
Console.Read();
}
}
class C : B
{
public void somerandommethod()
{
// some random method not really relevant to this example.
}
}
static void Main(string[] args)
{
A a = new C();
a.print(); // it will now print B (since B has the most derived implementation of print())
}
希望这个答案有帮助
最佳。调用实际实例的最派生部分-如果实例化B,则会打印B。尝试
A=newb();a、 打印()代码>或A=新的C();a、 打印()
@Marwie它会打印a,它会打印B或C。试试看。作为一个思维实验,想象另一个类D:B
。。。在你的例子中,如果它应该输出“C called”,那么它会用额外的类写“C called”或“D called”(显然答案是两者都不是)。但是为什么要使用“最派生”的版本呢?作者可能只会说“派生”的版本。还有什么吗?作者可能是想说,如果您创建了most派生的实例,那么将调用most派生的重写实现。@Arbaaz您已经重写了同一个方法两次。因此,如果像Ehsan Sajjad的示例中那样执行a.print()
,将执行该方法最派生的版本。对于C的实例,C的print
方法将获胜-即使C是从B派生的,B本身已经实现了print
。