多态性和虚拟方法

本文关键字:方法 虚拟 多态性 | 更新日期: 2023-09-27 18:12:30

假设Vehicle类包含一个名为 CalculateMaxSpeedvirtual方法。假定 MotorVehicle 类和 Automobile 类都override此方法。哪个类定义执行后续代码中的第二条语句时调用的方法?

Vehicle(Automobile的祖父母(> MotorVehicle(父母 Auatomobile (> Automobile

MotorVehicle car = new Automobile();
car.CalculateMaxSpeed();

好吧,在我看来,它应该是Automobile#CalculateMaxSpeed的,但我担心它可以MotorVehicle#CalculateMaxSpeed,因为它包含MotorVehicle的实例 Automobile .请有人详细说明。

多态性和虚拟方法

你的理解是正确的。 将调用Automobile#CalculateMaxSpeed。这称为 Runtime Polymorphism .

虽然 car 对象的类型是 MotorVehicle 的,但在运行时,对象的内容将被标识为派生类类型,即 Automobile 。因此,调用该方法不是基于对象的类型,而是基于对象的内容。

类型将由编译器使用,但调用该方法的实际决定是在运行时根据对象的内容完成的。

如果使用具体类或基类键入引用,则键入与调用的内容无关,除非使用标识符重用:

public class A 
{
     public virtual string Text { get; set; }
}
public class B : A
{
     // "new" keyword is identifier reusing. You're
     // defining a new member which uses Text again and
     // hides "Text" to references typed as B
     new public string Text { get; set; }
}
public class X : A
{
     public override string Text { get; set; }
}

B someB = new B();
someB.Text = "hello world";
// Now try to access Text property... what happened?
// Yes, Text property is null, because you're reusing the 
// identifier in B instead of overriding it
A someBUpcastedToA = someB;
string text = someBUpcastedToA.Text;
X someX = new X();
someX.Text = "goodbye";
// Now if you access someXUpcastedToA.Text
// property it will give you the "goodbye" string
// because you're overriding Text in X instead of
// reusing the identifier
A someXUpcastedToA = someX;
归根结底,类型是向对象引用提供或多或少的

元数据,并提供对当前类型成员的访问,但存储在所谓的引用中的对象仍然是相同的,如果它或多或少是类型化的。

考虑像显示或隐藏给定对象的详细信息一样键入:

// someX reference provides access to all X members
X someX = new X();
// This is upcasting. Now it's still the X instance but
// with access to less members. 
A a = someX;

重写只是重用方法或属性签名(即 public string Text (,并在派生类中更改其主体。当方法标记为虚拟抽象时,编译器和运行时知道它是一个多态类成员,运行时将为给定的多态成员调用最具体的实现。这就是键入不会更改由引用框住的对象背后的原因