多态和虚方法

4
假设Vehicle类包含一个名为CalculateMaxSpeed的虚方法。假设MotorVehicle和Automobile类都覆盖了这个方法。在执行下面代码的第二条语句时,哪个类定义的方法被调用?
Vehicle类(Automobile的祖先类)> MotorVehicle类(Auatomobile的父类)> Automobile类
MotorVehicle car = new Automobile();
car.CalculateMaxSpeed();

在我看来应该是Automobile#CalculateMaxSpeed,但我担心它可能是MotorVehicle#CalculateMaxSpeed,因为MotorVehicle包含Automobile的实例。请有经验的人解释一下。

2个回答

2
您的理解是正确的。将调用Automobile#CalculateMaxSpeed。这被称为运行时多态性
虽然汽车对象的类型是MotorVehicle,但在运行时,对象的内容将被识别为派生类类型,即Automobile。因此,该方法将不基于对象的类型而是基于对象的内容来调用。
编译器将使用类型,但实际决定调用方法是根据对象内容在运行时进行的,保留HTML标签。

0

无论您使用具体类还是基类输入引用,类型与“如何调用”无关,除非您使用标识符重用:

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)并更改其主体。当一个方法被标记为virtualabstract时,编译器和运行时知道它是一个多态类成员,并且运行时将调用给定多态成员的最具体实现。这就是为什么类型不会改变由引用装箱的对象的原因


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接