2017-03-17 43 views
1

以下類型不匹配是我的代碼: -與多態性的ArrayList

ArrayList<animal> myanimals = new ArrayList<animal>(); 
dog adog = new dog(); 
myanimals.add(adog); 
System.out.println("" + myanimals.get(0).getClass()); 
dog newdog = myanimals.get(0); 

我已經創建了一個ArrayList動物(超)myanimals和存儲在狗(子類)爲第一要素。然後myanimals.get(0)返回一個狗型對象。當這種狗類型的對象是由在聲明dog newdog = myanimals.get(0)狗類參考書中提到,它顯示了一個錯誤說:

類型不匹配,不能從動物轉換爲狗。

爲什麼會發生這種情況?

+3

歡迎來到StackOverflow。請將代碼和錯誤發佈爲文字,而不是圖片 –

+0

感謝您的編輯建議。 @Shashwat –

回答

4

方法調用myanimals.get(0)返回類型爲Animal的對象引用。嘗試TypecasatingAnimal作爲dog,如: -

dog newdog = (dog)myanimals.get(0); 

編輯1:你問到下面的行

System.out.println(myanimals.get(0).getClass()); 

這實際上打印出dog的輸出。爲什麼?我們來看看一些觀點。

你覺得下面的程序應該輸出:

animal a = new dog(); 
System.out.println(a.getClass()); 

此打印出dog預期。但是,這並不意味着我們可以做到這一點: -

animal a = new dog(); 
dog d = a; 

這將拋出一個編譯時錯誤。你的情況同樣如此。據說ArrayList包含animal。因此,即使您爲其添加dog,它也會返回animal

+0

但是命令:** System.out.println(「」+ myanimals.get(0).getClass()); **將輸出顯示爲**「class polymorph.dog」**。這是否意味着** myanimals.get(0)**返回一個狗對象? –

+0

雖然正確,但這並不回答關於「爲什麼」不允許的OP問題 – bc004346

+0

@AayushTaneja現在查看我的答案。我希望這個編輯能夠解決問題。 –

0

基本上,ArrayList的類型是animal,您可以在其中添加任何種類的動物,不只是狗,還包括貓,老鼠和鸚鵡。雖然基本類型的確是dog,但您無法安全地知道這一點。否則,您將遇到運行時異常,如下所示:

ArrayList<Animal> myanimals = new ArrayList<Animal>(); 
Cat myCat = new Cat(); 
myanimals.add(myCat); 
System.out.println("" + myanimals.get(0).getClass()); 
Dog newdog = myanimals.get(0); // <-- this would be runtime exception if Java compiler allowed this 
+2

非常感謝。這非常有幫助。 @ bc004346 –

2

Java是靜態類型語言。即Java編譯器根據源代碼檢查類型不匹配的代碼。你的源代碼說,myanimals.get(0)是動物類型。

繼承是「IS-A」關係,即狗IS-A動物,可以用作動物類型變量的值。但是相反的事實並非如此:動物不是IS-A狗,它可能是(它使得鑄造成爲可能 - 稍後會有更多)。這就是爲什麼你會遇到類型不匹配的原因。

它只是在運行時,很久以後你的源代碼被編譯成字節碼(和泛型類型被擦除),myanimals.get(0).getClass()似乎是巧合的狗。編譯器之前無法知道。

這是有道理的:它可以防止可能被靜態分析捕獲的運行時錯誤。

但是,你是開發者,他肯定知道myanimals.get(0).getClass()在運行時是Dog類型的,所以你可以承擔責任並且在Shashwat的回答中應用cast。編譯器仍然檢查這樣的轉換是否可能,如果是的話 - 它會相信你的話。

+0

非常感謝您的幫助。 @iTollu –

+0

@ aayush-taneja歡迎您! – iTollu