当超类没有实现接口而是子类时,在接口子类和超类之间进行转换

时间:2013-11-28 10:21:40

标签: java inheritance interface casting

在以下代码中

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之间没有关系?如果没有什么可能是原因。谢谢!!

7 个答案:

答案 0 :(得分:6)

编译器只检查是否存在可能的关系,并且只有一个:

LandMover可能是Car,而后者又是IS-A Vehicle。由于您通过使用显式强制转换来保证此转换正常,因此编译器很高兴。

答案 1 :(得分:1)

不,因为

    LandMover lmv = porsche;

不会声明LandMover类型的对象,而是通过引用“LandMover”引用“Car”类型的对象。编译器知道这是'Car'类型的对象(注意:'Car'和'Vehicale'在同一个继承树中)。

答案 2 :(得分:0)

通过显式转换为Vehicle,编译器不会告诉你任何事情。你可能只是在运行时得到一个异常,如果关系最终没有完全解决并且你正在构建一些实际上不是Vehicle

的东西

答案 3 :(得分:0)

使用您提供的代码进行编译即可。 lmv = porsche;与说

相同
public class Car extends Vehicle implements LandMover {

    public static void main(String args[]){

        LandMover car = new Car();
    }
}

Car实现了LandMover,因此您可以将其用作多态参考。所以到目前为止没问题。

Vehicle vec = (Vehicle)lmv;

现在你说LandMover(参考)很可能是一辆汽车,实际上是一辆汽车。所以编译器不会抱怨。

但请注意此类型强制转换后,如果您尝试在vec上调用未在Vehicle类中定义的某些函数(甚至不是Car类中的函数,尽管它实际上是Car类的运行时实例)编译器会投诉。

这是因为在运行时编译器只检查引用类的类,如果在其中定义了(可能没有实现)被调用的函数,那么就不会有任何编译错误。

答案 4 :(得分:0)

不会有任何编译错误。这是因为类可以实现许多接口,因此给定的“LandMover”实例可以是Vehicle。但是,由于类可以从单个超类继承,因此您知道不能将'java.lang.String'转换为'Vehicle',因为它们不共享除object之外的公共超类。

答案 5 :(得分:0)

考虑层次结构

Car extends Vehicle

&安培;

Car implements LandMover

对于强制转换Vehicle vec = (Vehicle)lmv;,编译器可以检查静态(编译时),lmv的类型LandMover以及 CAN 为Car(为Car implements LandMover)。现在作为Car extends Vehicle,编译器不会抱怨。

确认,尝试按如下方式评论代码

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

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

答案 6 :(得分:-1)

由于无法实例化抽象类,因此会出现错误 更多参考这个 post