0

当父变量类型存储子对象并调用被子类覆盖的方法时会发生什么?

方法的父版本执行还是方法的子版本执行?

public class testa
{
    public virtual void display()
    {
        System.Diagnostics.Debug.WriteLine('a');
    }
}

public class testb : testa
{
    public override void display()
    {
        System.Diagnostics.Debug.WriteLine('b');
    }
}

然后在某处打电话

testa b = new testb();
b.display();

通过我自己运行这个测试,我发现它说“b”,但我仍然想要一个正式的答案,以完全理解正在发生的事情。

4

2 回答 2

2

您指的是运行时多态性。当一个virtual method is called对象上,那么most derived version方法gets called总是。

就像您的情况一样,您正在调用在类display中被覆盖的(虚拟)方法。testb因此,它被调用来显示b

testa b = new testb();
b.display();

但是,如果您使用method hidingusingnew关键字 -

public class testa
{
    public void display()
    {
        System.Diagnostics.Debug.WriteLine('a');
    }
}

public class testb : testa
{
    public new void display()
    {
        System.Diagnostics.Debug.WriteLine('b');
    }
}

然后你运行这段代码 -

testa b = new testb();
b.display();

你会看到a得到打印,因为base class method gets called它的no more virtual.

如果还不清楚,请参阅链接覆盖 VS 方法隐藏以获取更详细的说明。

于 2013-07-21T07:14:52.300 回答
1

当您创建一个包含虚函数的类时,您会得到一个称为虚拟表(或 vtable)的东西。vtable 按类中的地址保存指向类中所有虚函数的指针。

当你持有指向实际上是派生类的父类的指针并调用虚函数时,访问虚表以获取函数的地址,并以实际派生类型运行函数。

这是一个很大的话题,您最好阅读更多内容以了解我未提及的内容,例如对象大小如何随指针大小增加或 vtable 实际保存在哪里

http://en.wikipedia.org/wiki/Virtual_method_table

于 2013-07-21T06:56:45.973 回答