2013-11-28 41 views
4

在下面的代码接口sublass和超类之间铸造时超类未实现的接口,但子类是

abstract class Vehicle { } 
class Car extends Vehicle implements LandMover { } 
interface LandMover { } 
    Car porsche=new Car(); 
    LandMover lmv; 
    lmv = porsche; 
    Vehicle vec = (Vehicle)lmv; 

不应该有在第四行编译错误因为有类车辆和接口LandMover之间没有关系? ?如果没有,可能是什么原因。谢谢!

+0

当你尝试时发生了什么? –

+0

@Kugathasan我试过它不显示任何编译错误,我有点困惑,现在答案 – unknown

回答

6

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

LandMover可以是Car,其依次是IS-A Vehicle。由于您承诺通过使用明确的转换可以实现此转换,编译器很高兴。

+0

好的谢谢你的主动和回答:) – unknown

-1

会有错误作为抽象类不能被实例化 更多参考本 post

+0

,但我没有实例化抽象类... – unknown

+0

他没有实例化抽象类。他实例化了子类,并使用超类变量来保存引用。 – latenightcode

0

通过明确地转换为Vehicle,编译器不会告诉你任何东西。你可能只是在运行时获取的异常,如果关系终于有点不工作了,你是铸造的东西,其实并不是一个Vehicle

1

没有,因为

LandMover lmv = porsche; 

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

0

编译将会与您提供的代码一致。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类中的函数),但请注意。

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

0

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

0

考虑层级

Car extends Vehicle

&

Car implements LandMover

对于铸造Vehicle vec = (Vehicle)lmv;编译器可检查静态(编译时间),的lmv其类型是LandMover和这反过来也是CANCar(如Car implements LandMover)。现在作为Car extends Vehicle编译器不会抱怨。

以确认,请尝试注释的代码如下

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

这里,编译器是确保lmvCAN NOTVehicle肯定的,因此标志错误。

+1

编译失败,由于'lmv'未被初始化如果你设置lmv = null它编译好。 –

+0

它会给运行时异常(类抛出异常)编译罚款,因为编译器认为有一种可能性,抽象类车辆扩展由另一个类和kappil给出了上述解释expilcit铸造将不会给任何编译错误 – unknown

+0

@DevBlanked谢谢指出它。 – Santosh