c#多态性的概念
本文关键字:多态性 | 更新日期: 2023-09-27 17:53:57
下面代码:
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");
}
}
结果是'son'。
如果我将' public override void show()
'修改为' public new void show()
',结果是'father'。
所以我总结如下'规则':
- 使用'override',调用哪个函数是在运行时确定的时间。程序会根据。选择合适的功能当前对象的实际类型。(如上所述,f的运行时类型是son,所以它调用儿子的节目。)
- 使用'new'修饰符,确定何时调用哪个函数它被编译。程序将选择对象声明的类型为调用它的函数。(如上所述,f的声明类型是father,所以使用'new'修饰符使输出显示'father'。
以上就是我对多态性的理解。有什么误解和错误吗?
使用'new'修饰符,编译时确定调用哪个函数。程序将选择对象声明的类型来调用它的函数。(如上所述,f的声明类型为father,因此使用'new'修饰符使输出显示为'father'。
没有。这个决定仍然是在执行时做出的,但是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
中的实现才是实际执行的。
使用'new'修饰符,编译时确定调用哪个函数。程序将选择对象声明的类型来调用它的函数。(如上所述,f的声明类型为father,因此使用'new'修饰符使输出显示为'father'。
这有点错。使用new
意味着这个函数不覆盖基类的任何函数。函数分派仍然在运行时发生,但不考虑此函数。如果您有孙子类或女儿类来进行更多的测试,那么差异将更加明显。
是的,它是这样工作的…你的理解是对的。
但对于第二种情况,当你使用new
而不是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有很好的例子:知道何时使用覆盖和新关键字(c#编程指南)
普通方法由类的类型调用,虚拟方法由分配给对象的内存内容调用。现在关键字new
隐藏了多态的概念,只关心它的类型。