代码如下:
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");
}
}
结果是'儿子'
如果我将“public override void show()
”修改为“public new void show()
”,则结果为“父亲”。
所以我在下面的'规则'中总结:
以上都是我对多态性的理解。任何误解和错误?
答案 0 :(得分:5)
使用'new'修饰符,在编译时确定将调用哪个函数。程序将选择对象的声明类型来调用它的函数。(如上所述,f的声明类型是父,所以使用'new'修饰符使输出显示为“父亲”。
不是真的。仍然在执行时做出决定,但new
方法 not 覆盖基类中的虚方法。通过稍微扩展您的示例可以很容易地显示出来:
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
}
}
此处,在编译时,决定调用覆盖最多的Base.Foo
实现 - 如果有多个Foo
签名,则决定使用哪个签名例如,将被采取。当然,在这一点上,哪个实现将是“被覆盖最多的”。
在执行时间,CLR将根据目标对象的实际类型(MoreDerived
)找到大多数被覆盖的实现。但是MoreDerived.Foo
不会覆盖Base.Foo
...而Derived.Foo
会这样做,因此Derived
中的实现是实际执行的实现。
答案 1 :(得分:2)
是的,它的工作方式只是......你的理解是对的......
但对于使用new
intad override
的第二种情况,它隐藏了实际的实现,即父类实现
由于new关键字用于定义此方法,因此不会调用派生类方法 - 而是调用基类方法。
来自MSDN的示例
// Define the base class
class Car
{
public virtual void DescribeCar()
{
System.Console.WriteLine("Four wheels and an engine.");
}
}
// Define the derived classes
class ConvertibleCar : Car
{
public new virtual void DescribeCar()
{
base.DescribeCar();
System.Console.WriteLine("A roof that opens up.");
}
}
class Minivan : Car
{
public override void DescribeCar()
{
base.DescribeCar();
System.Console.WriteLine("Carries seven people.");
}
}
致电课程
Car[] cars = new Car[3];
cars[0] = new Car();
cars[1] = new ConvertibleCar();
cars[2] = new Minivan();
输出
Car object: YourApplication.Car
Four wheels and an engine.
----------
Car object: YourApplication.ConvertibleCar
Four wheels and an engine.
----------
Car object: YourApplication.Minivan
Four wheels and an engine.
Carries seven people.
----------
MSDN有很好的例子:Knowing When to Use Override and New Keywords (C# Programming Guide)
答案 2 :(得分:2)
使用'new'修饰符,在编译时确定将调用哪个函数。程序将选择对象的声明类型来调用它的函数。(如上所述,f的声明类型是父,所以使用'new'修饰符使输出显示为“父亲”。
这有点不对劲。使用new
意味着此函数不会覆盖基类的任何函数。函数调度仍然在运行时发生,但不考虑此函数。如果您有Grandson或Daughter类来测试更多,那么差异会更清楚。
答案 3 :(得分:1)
通过类的类型调用普通方法,并且通过分配给对象的内存的内容调用虚方法。现在关键字new
隐藏了多态的概念,只关心它的类型。