假设Vehicle
类包含名为virtual
的{{1}}方法。假设CalculateMaxSpeed
和MotorVehicle
类Automobile
这个方法。哪个类定义了执行后面代码中的第二个语句时调用的方法?
override
(Vehicle
的祖父母)>Automobile
(父母的MotorVehicle
)>Auatomobile
Automobile
我认为它应该是MotorVehicle car = new Automobile();
car.CalculateMaxSpeed();
但我担心Automobile#CalculateMaxSpeed
因为MotorVehicle#CalculateMaxSpeed
包含MotorVehicle
的实例。请有人详细说明。
答案 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 标记时,编译器和运行时知道它是多态类成员,运行时将为给定的多态成员调用最具体的实现。 这就是打字没有改变由参考装箱的对象这一事实背后的原因。