当父变量类型存储子对象并调用重写的方法时会发生什么
本文关键字:方法 什么 重写 调用 类型 变量 存储 对象 | 更新日期: 2023-09-27 18:24:09
当父变量类型存储子对象并调用被子类重写的方法时会发生什么?
方法的父版本执行还是子版本执行?
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",尽管我仍然希望得到一个正式的答案,以完全了解正在发生的事情。
您指的是运行时多态性。当一个对象上有一个virtual method is called
时,那么方法的most derived version
总是gets called
。
与您的情况类似,您正在调用display
(虚拟)方法,该方法在testb
类中被覆盖。因此,它被调用来显示b
。
testa b = new testb();
b.display();
但是,如果您使用method hiding
,则使用new
关键字-
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方法隐藏链接以获得更详细的解释。
当您创建一个包含虚拟函数的类时,您会得到一个称为虚拟表(或vtable)的东西vtable通过类中的地址保存指向该类中所有虚拟函数的指针。
当您持有指向父类(实际上是派生类)的指针并调用虚拟函数时,将访问vtable以获取函数的地址,并以实际派生类型运行函数。
这是一个大主题,你最好读一读。还有一些我没有提到的东西,比如对象大小是如何随着指针的大小而增加的,或者vtable实际保存的在哪里
http://en.wikipedia.org/wiki/Virtual_method_table