2013-08-19 133 views
1

當我嘗試與Colorable接口指向Car類的對象,而無需使用工具類汽車i未顯示任何編譯錯誤(雖然它顯示運行時錯誤)(問題1)和當我嘗試對班級做同樣的事情,我不會延長車輛等級,並嘗試用車輛類別指示車輛的對象,它立即顯示編譯錯誤。爲什麼?接口參考變量

問題1:

interface Colorable {} 

class Vehicle {} 

class Car extends Vehicle {} 

public class Tester { 

    public static void main(String[] args) { 

    Car c=new Car(); 
    Vehicle a = (Vehicle)c; 

    Colorable i = (Colorable)c; 

    System.out.println("Successful"); 
    } 
} 

問題2:

interface Colorable {} 

class Vehicle {} 

class Car {} 

public class Tester { 

    public static void main(String[] args) { 

    Car c=new Car(); 
    Vehicle a = (Vehicle)c; 

    Colorable i = (Colorable)c; 

    System.out.println("Successful"); 
    } 
} 
+4

當您輸入問題時,編輯區域旁邊有一個方便的** How to Format **框。值得一讀。在下面還有一個預覽,您可以在其中看到您的問題的樣子,以及編輯區域上方的格式化工具欄。由於這不是你的第一個問題,請在發佈之前花時間清楚地設置事物的格式,而不是依賴像拉胡爾這樣的人爲你做。 –

+0

問題2:由於Car沒有實現該接口,因此不能將c轉換爲Colorable(「Colorable i =(Colorable)c;」)。但是,如果您可以向我們顯示您引用的錯誤輸出,它會非常有幫助。 – tbsalling

+0

也許你會得到至少一個編譯警告有關選中鑄件... –

回答

8

這是可能的Car一個子類的實例來實現Colorable,這就是爲什麼它不是一個編譯期時間錯誤。

然而,在問題2鑑於VehicleCar是完全獨立的層次,編譯器知道這是不可能的任何Car參考也是的Vehicle實例的引用...所以它可以拒絕編譯時間。

基本上,類和接口之間的區別在於接口可以在類型層次結構下面實現,而層次結構中有一個繼承鏈,這意味着編譯器可以檢測到更多問題。

如果Car被標記爲final,編譯器將同樣能夠告訴它的Car一個實例是不可能的,也能實現Colorable,並將是一個編譯時錯誤太多。

+0

但如果你採取下面的示例類可着色{} 類車{} 類汽車整車擴展{} 公共類測試儀{ 公衆static void main(String [] args){c0 = new Car(); 車輛a = c; Colorable i = c; System.out.println(「Successful」); } } – user2662247

+0

@ user2662247:那麼是什麼?你沒有說過你會發生什麼。 –

+0

在上面的代碼中,汽車的子類(例如車輛)也可以繼承可着色的類,所以如果我寫車輛延伸可着色,那麼程序成功執行,但是如果我不延長它在車輛中,如我已經顯示上面的例子,那麼它是一個編譯錯誤,如果我使可見的接口,而不是類的運行時錯誤。 – user2662247

2

在編譯期間,類層次結構是已知的。 Java立即知道是否Car是-a Vehicle

接口更棘手。考慮以下代碼:

interface Colorable {} 

class Vehicle {} 

class Car extends Vehicle implements Colorable {} 

{ 
    // case 1: 
    Vehicle vehicle1 = new Vehicle(); 
    Colorable colorable = vehicle1; // error 

    // case 2: 
    Vehicle vehicle2 = new Car(); 
    Colorable colorable2 = vehicle2; // OK! Car implements Colorable! 
} 

即使一個Vehicle沒有實現ColorableVehicle實力的子類。因此運行時不會編譯時錯誤。

+0

您的上面的代碼是可以的,因爲vehicle2引用變量保存了我正在傳遞的汽車的引用ID colorable2,它也可以保存汽車變量的參考ID。但在case1中,您正在嘗試將車輛類別引用ID分配給可能的着色參考變量,例如。考慮我的下一個評論中給出的代碼。 – user2662247

+0

類着色的{} 類車輛延伸着色的{} 類汽車延伸車輛{} 公共類測試儀{ 公共靜態無效的主要(字串[] args){ 轎廂C =新車(); 車輛a = c; Colorable i = c; System.out.println(c); System.out.println(a); System.out.println(i); } } – user2662247

0

在第一種情況下

Car c=new Car(); 
Vehicle a = (Vehicle)c; 
Colorable i = (Colorable)c; 

有兩兩件事 -

  1. 要創建一個Car對象。然後,您使用Vehicle參考指向由於您的Car類擴展Vehicle類而有效的汽車對象。
  2. 然後您使用Colorable參考指向汽車對象。現在有可能某些汽車子類實現Colorable接口。例如

    class myCar extends Vehicle implements Colorable{}

,然後你做

Car c=new myCar(); 
Colorable i = (Colorable)c; 

這不應該拋出運行時異常。在你的情況下,你告訴編譯器相信你會有一些可以實現可着色接口的類車子類,但事實並非如此。所以你會得到一個編譯時錯誤,但是當你違反這個信任時,你會得到一個運行時錯誤。

+0

假設我將界面着色爲可着色的類,如果我將該可着色類延伸到車輛類,那麼我可以用可着色的參考變量指向該車對象。但是,如果現在不延長可着色到車輛,是一個編譯錯誤..但在接口的情況下它是運行時。 – user2662247