2013-11-28 43 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