2013-10-02 53 views
8

很顯然,這會導致編譯錯誤,因爲主席是不相關的貓:的Java:鑄造一類無關的接口

class Chair {} 
class Cat {} 

class Test { 
    public static void main(String[] args) { 
     Chair chair = new Char(); Cat cat = new Cat(); 
     chair = (Chair)cat; //compile error 
    } 
} 

爲什麼那麼,我只能在運行時得到一個異常我將Cat引用投射到不相關的接口Furniture上,而編譯器可以明顯地告訴Cat沒有實現Furniture?

interface Furniture {} 

class Test { 
    public static void main(String[] args) { 
     Furniture f; Cat cat = new Cat(); 
     f = (Furniture)cat; //runtime error 
    } 
} 
+0

因爲多態性在運行時發生。 –

+0

但編譯器知道Cat沒有實現Furniture,並且在運行時無法更改?我可能會錯過一個簡單的觀點,但你的回答並不能真正幫助我 – enp4yne

+0

因爲。即使貓可能不直接實施傢俱,也可能有一些超級貓。編譯器選擇不去挖掘這些醜陋的細節,因爲接口規則非常複雜。 (謝謝Sun)並沒有一般的規則要求編譯器檢測不可避免的運行時異常(例如除以零) - 它更像是它提供的「服務」。 –

回答

12

之所以這樣編譯

interface Furniture {} 

class Test { 
    public static void main(String[] args) { 
     Furniture f; Cat cat = new Cat(); 
     f = (Furniture)cat; //runtime error 
    } 
} 

是,你很可能有

public class CatFurniture extends Cat implements Furniture {} 

如果創建一個CatFurniture例如,你可以把它分配給Cat cat和實例可以鑄造到Furniture。換句話說,某些Cat子類型可能實現了Furniture接口。

在你的第一個例子

class Test { 
    public static void main(String[] args) { 
     Chair chair = new Char(); Cat cat = new Cat(); 
     chair = (Chair)cat; //compile error 
    } 
} 

這是不可能的,一些Cat亞型延伸Chair除非Cat本身Chair延伸。

+4

如果'Cat'被聲明爲final,那麼編譯器確實會抱怨(它會知道沒有Cat的子類可以實現'Furniture'可能沒有Cat的子類)。 –