在下面的代码中
abstract class Vehicle { }
class Car extends Vehicle implements LandMover { }
interface LandMover { }
Car porsche=new Car();
LandMover lmv;
lmv = porsche;
Vehicle vec = (Vehicle)lmv;
第 4 行不应该有编译器错误,因为类车辆和接口 LandMover 之间没有关系吗?? 如果没有,可能是什么原因。谢谢!!
编译器只检查是否存在可能的关系,并且存在:
LandMover
可以是Car
,而IS-A又Vehicle
。由于您承诺使用显式强制转换可以进行此转换,因此编译器很高兴。
不,因为
LandMover lmv = porsche;
不声明 LandMover 类型的对象,但通过引用"LandMover"引用类型为"Car"的对象。编译器知道这是一个类型为"Car"的对象(注意:"Car"和"Vehicale"在同一个继承树中(。
通过显式转换为Vehicle
,编译器不会告诉你任何事情。如果关系最终没有完全解决,并且您正在转换实际上不是Vehicle
的内容,您可能会在运行时收到异常
将适用于您提供的代码。 lmv = porsche;
等于说
public class Car extends Vehicle implements LandMover {
public static void main(String args[]){
LandMover car = new Car();
}
}
汽车实现了LandMover,因此您可以将其用作多态参考。所以到目前为止没有问题。
Vehicle vec = (Vehicle)lmv;
现在你说的LandMover(参考(很可能是一辆汽车,实际上是一辆汽车。所以编译器不会抱怨。
但请注意,在此类型转换之后,如果您尝试在车辆类中未定义的vec
上调用某些函数(甚至不是 Car 类中的函数,尽管实际上它是 Car 类的运行时实例(,编译器会抱怨。
这是因为在运行时编译器只检查引用类型的类,如果调用的函数在其中定义(可能无法实现(,则不会有任何编译错误。
不会有任何编译错误。这是因为一个类可以实现许多接口,因此给定的"LandMover"实例可以是车辆。但是,由于类可以从单个超类继承,因此您知道不能将"java.lang.String"转换为"Vehicle",因为它们除了对象之外不共享公共超类。
考虑层次结构
Car extends Vehicle
&
Car implements LandMover
对于转换Vehicle vec = (Vehicle)lmv;
编译器可以静态检查(编译时(,LandMover
的lmv
类型,而类型也可以Car
(如Car implements LandMover
(。现在Car extends Vehicle
编译器不会抱怨。
要确认,请尝试按如下方式注释代码
//Car porsche=new Car();
LandMover lmv;
//lmv= porsche;
Vehicle vec = (Vehicle)lmv; //Compiler error
在这里,编译器确定lmv
肯定不能Vehicle
,因此标记错误。
会出现错误,因为抽象类无法实例化欲了解更多信息,请参阅此处发布