我理解以下代码如何工作,基于多态和动态绑定。 Java在某种程度上能够在运行时弄清楚因为vh是一个MotorBike,我们应该调用MotorBike的move()方法。
class Vehicle{
public void move(){
System.out.println(“Vehicles can move!!”);
}
}
class MotorBike extends Vehicle{
public void move(){
System.out.println(“MotorBike can move and accelerate too!!”);
}
}
class Test{
public static void main(String[] args){
Vehicle vh=new MotorBike();
vh.move(); // prints MotorBike can move and accelerate too!!
}
}
我不明白为什么以下代码会中断。我所做的唯一改变是从Vehicle类中删除move()方法。现在我收到一个编译错误,上面写着“找不到符号 - 方法move()”。为什么会这样?为什么上一个示例有效并且此代码不起作用?
class Vehicle{
}
class MotorBike extends Vehicle{
public void move(){
System.out.println(“MotorBike can move and accelerate too!!”);
}
}
class Test{
public static void main(String[] args){
Vehicle vh=new MotorBike();
vh.move(); // compile error
}
}
答案 0 :(得分:0)
Java有两个密切相关的概念,它们都是相关的:
vh
的类型为Vehicle
,因此表达式vh
(仅包含该变量)的类型为Vehicle
。
new MotorBike()
的类型为MotorBike
,但由于这是Vehicle
的子类型,编译器可以从前者转换为后者。 / LI>
new MotorBike()
使用运行时类型MotorBike
创建一个对象。当您编写vh.move()
时,如果Vehicle
类没有名为move
的方法,则编译器不知道您在谈论什么。
如果Vehicle
有一个名为move
的方法,那么编译器可以很好地编译它,并将它留给运行时来检查实际的运行时类型相应的实例并发送到正确的方法。 (或者如果 没有相应的实例,则提出NullPointerException
,因此没有相关的运行时类型。)
有一些语言,通常称为"动态输入" (或"无类型"或"动态"),没有 type 的概念,只有运行时的概念 - 输入的。这些语言包括Perl,Python,JavaScript等等。在这些语言中,vh.move()
的模拟在所有情况下都会被接受,并且运行时会在调用之前验证该方法是否存在。但Java程序员更喜欢使用更智能的编译器,这有助于我们在编译类型中检测更多错误。