代码如下:
public class Program
{
static void Main(string[] args)
{
father f = new son(); Console.WriteLine(f.GetType());
f.show();
}
}
public class father
{
virtual public void show()
{
Console.WriteLine("father");
}
}
public class son : father
{
public override void show()
{
Console.WriteLine("son");
}
}
Run Code Online (Sandbox Code Playgroud)
结果是'儿子'.
如果我修改' public override void show()'到' public new void show()',结果是'父亲'.
所以我在下面的"规则"中总结:
以上都是我对多态性的理解.任何误解和错误?
使用'new'修饰符,将在编译时确定将调用的函数.程序将选择对象的声明类型来调用其函数.(如上所述,f的声明类型是父,所以使用'new'修饰符使输出显示'父亲'.
并不是的.这一决定仍然在执行时做,但new方法并不能覆盖在基类中的虚方法.通过稍微扩展您的示例可以很容易地显示出来:
using System;
class Base
{
public virtual void Foo()
{
Console.WriteLine("Base.Foo");
}
}
class Derived : Base
{
public override void Foo()
{
Console.WriteLine("Derived.Foo");
}
}
class MoreDerived : Derived
{
public new void Foo()
{
Console.WriteLine("MoreDerived.Foo");
}
}
class Test
{
static void Main()
{
Base x = new MoreDerived();
x.Foo(); // Prints Derived.Foo
}
}
Run Code Online (Sandbox Code Playgroud)
这里,在编译时,决定调用最重要的实现Base.Foo- 例如,如果有多个Foo签名,则决定使用哪个签名.当然,在这一点上,哪个实现将是"被覆盖最多的".
在执行时,CLR将根据目标对象的实际类型找到大多数被覆盖的实现 - 即MoreDerived.但是MoreDerived.Foo不会覆盖Base.Foo......反之Derived.Foo,所以实现Derived是实际执行的.