多态性与虚方法

时间:2015-09-12 08:08:33

标签: c# polymorphism

假设Vehicle类包含名为virtual的{​​{1}}方法。假设CalculateMaxSpeedMotorVehicleAutomobile这个方法。哪个类定义了执行后面代码中的第二个语句时调用的方法?

  

overrideVehicle的祖父母)> Automobile(父母的   MotorVehicle)> Auatomobile

Automobile

我认为它应该是MotorVehicle car = new Automobile(); car.CalculateMaxSpeed(); 但我担心Automobile#CalculateMaxSpeed因为MotorVehicle#CalculateMaxSpeed包含MotorVehicle的实例。请有人详细说明。

2 个答案:

答案 0 :(得分:2)

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

虽然汽车对象的类型是MotorVehicle,但在运行时,对象的内容将被识别为抽样类类型Automobile。因此,该方法不是基于对象的类型而是基于对象的内容来调用的。

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

答案 1 :(得分: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;

在一天结束时,键入会给对象引用提供更多或更少的元数据,并且它提供对当前类型成员的访问,但是存储在所谓引用中的对象仍然是相同的,如果它&# 39;或多或少打字。

考虑输入显示或隐藏给定对象的详细信息:

// 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)并在派生类中更改其主体。当方法用虚拟 abstract 标记时,编译器和运行时知道它是多态类成员,运行时将为给定的多态成员调用最具体的实现。 这就是打字没有改变由参考装箱的对象这一事实背后的原因。