当超类不实现接口但子类实现接口时,在接口子类和超类之间进行转换



在下面的代码中

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;编译器可以静态检查(编译时(,LandMoverlmv类型,而类型也可以Car(如Car implements LandMover(。现在Car extends Vehicle编译器不会抱怨。

要确认,请尝试按如下方式注释代码

        //Car porsche=new Car();
         LandMover lmv;
         //lmv= porsche;
         Vehicle vec = (Vehicle)lmv; //Compiler error

在这里,编译器确定lmv肯定不能Vehicle,因此标记错误。

会出现错误,因为抽象类无法实例化欲了解更多信息,请参阅此处发布

最新更新