新关键字:为什么不调用派生方法? [英] New keyword: why is the derived method not called?

查看:91
本文介绍了新关键字:为什么不调用派生方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有简单的三个班级:

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");
    }
}

我正在创建对象并调用其方法:

And I am creating objects and calling their methods:

A a = new A();
a.Write();

A b = new C();
b.Write();

C c = new C();
c.Write();

输出将是:ABC

我不明白的是为什么这些代码会产生B?:

What I cannot understand is why these code produces B?:

A b = new C();
b.Write();

我认为应该是C.但是,我测试了很多次,并且始终为B.

I thought that it should be C. However, I tested many times, and it is always B.

我了解到A b = new C()创建了C的新对象类型.因此输出应为C.还是在不使用强制转换的情况下调用覆盖方法是一种特殊的行为?

I understand that A b = new C() creates new object type of C. So output should be C. Or it is special behavior to call overridden method when we use it without casting?

为什么会发生?由于我们没有使用任何对B类的引用.

Why does it happen? As we have not used any reference to B class.

推荐答案

如果您使用((C)b).Write();

使用new关键字,您不会覆盖C的Write方法,而是创建仅为C定义的新方法.因此,对于您的C,您实际上有2个方法的名称为Write. /p>

With the new keyword you're not overriding the Write method for C but rather creating a new method only defined for C. So for your C you actually have 2 methods with a method name 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时也会发生同样的情况:

The same happens when you would define c as C:

C c = new C();

c.Write();          //Output "C"    
((A)c).Write();     //Output "B"

在第一个示例中,您正在调用C上定义的新方法.在第二行中,您从A中调用了Write方法,该方法被B覆盖,因此输出为"B".

In the first example you're calling the new method defined on C. In the second line you are calling the Write method from A, which is overridden by B, hence the output "B".

(更多说明)

变量c的类型为A,因此编译器知道"c是A的实例" ,但实际上它不是派生类型.当您在其上调用方法Write时,它将调用在A(由B覆盖)上定义的方法.基类A不了解在C上定义的新方法(这是new所做的,创建一个新方法),因此,除非您将其强制转换为C,以使编译器知道c的实际派生类型. ,您的基类的方法将被调用.

Variable c is of type A, so that's what your compiler knows "c is an instance of A", it is not known that it is actually of a more derived type. When you call the method Write on it, it will invoke the method defined on A (which is overriden by B). Your base class A has no knowledge of your new method defined on C (that's what new does, create a new method), so unless you cast it to C to let the compiler know about the actual, derived type of c, the method of your base class will be called.

这篇关于新关键字:为什么不调用派生方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆