多态性和虚拟方法
本文关键字:方法 虚拟 多态性 | 更新日期: 2023-09-27 18:12:30
假设Vehicle
类包含一个名为 CalculateMaxSpeed
的virtual
方法。假定 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
(,并在派生类中更改其主体。当方法标记为虚拟或抽象时,编译器和运行时知道它是一个多态类成员,运行时将为给定的多态成员调用最具体的实现。这就是键入不会更改由引用框住的对象背后的原因。