[英]Concept of C# polymorphism
下面的代码:
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()
”,则结果为“父亲”。
因此,我总结出以下“规则”:
以上是我对多态性的理解,是否有误解和错误?
使用'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
}
}
在这里,在编译时决定调用Base.Foo
的最重要的实现-例如,如果有多个Foo
签名,则将决定使用哪个签名。 当然,目前尚不知道哪个实现是“最重要的”。
在执行时 ,CLR将根据目标对象的实际类型( MoreDerived
找到最被重写的实现。 但是MoreDerived.Foo
不会覆盖Base.Foo
...,而Derived.Foo
可以,因此Derived
的实现是实际执行的。
是的,它的工作原理是……您的理解是正确的。
但是对于第二种情况,当您使用override
new
索引时,它将隐藏实际的实现,即父类实现
由于使用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就是一个很好的例子: 知道何时使用覆盖和新关键字(C#编程指南)
使用'new'修饰符,将在编译时确定要调用的函数。程序将选择对象的声明类型来调用其函数。(如上所述,f的声明类型为父亲,因此使用'new'修饰符使输出以显示“父亲”。
这有点不对。 使用new
表示此函数不会覆盖基类的任何函数。 函数分派仍然在运行时发生,但是不考虑该函数。 如果您有“孙子”或“女儿”课程来测试更多内容,则区别会更加明显。
通过类的类型调用普通方法,通过分配给对象的内存内容调用虚拟方法。 现在,关键字new
隐藏了多态的概念,只关心其类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.