2016-08-17 60 views
0

我想用Java編寫基於文本的遊戲,並且有問題。
我得到了一個HeadArmor對象extends Armorextends Item和這個implements IEquipable
如果我將HeadArmor對象添加到我的LinkedList並嘗試訪問它,它將成爲Item對象。Java列出多態性問題

private LinkedList<Item> items = new LinkedList<Item>(); 

該方法如何讓對象脫離列表。

public Item getItemByName(String name) {    
    int i = 0; 
    for (Item item : items) { 
     if (item.getName().equals(name)) { 
      //And the output is a Item Object and no HeadArmor 
      System.out.println(items.get(i).getClass().getName()); 
      return items.get(i); 
     }   
    i++; 
    } 
    return null; 
} 

因此,我無法檢查我的對象是否是HeadArmor的實例。

public boolean equip(String name){ 
     Item item = getItemByName(name); 
     //here he prints out I AM A DieWeltvonZuul.Item CLASS 
     System.out.println("I AM A "+item.getClass().getName()+ " CLASS"); 

     if(item instanceof Weapon){ 
      if (null != weapon) { 
       items.add(weapon); 
       weapon = (Weapon) item; 
      }else{ 
       weapon = (Weapon) item; 
      } 
     }else{ 
      //here he won't enter even the Object was at the beginning of type HeadArmor and this Object extends Armor 
      if (item instanceof Armor){ 
       changeItem((IEquippable) getItemByName(name)); 
      }else{ 
       return false; 
      } 
     } 
     return true; 
    } 

如果我嘗試將其轉換爲HeadArmor我得到

java.lang.ClassCastException: DieWeltvonZuul.Item cannot be cast to DieWeltvonZuul.HeadArmor 
+1

沒有與邏輯的問題。 – xenteros

+1

是否有任何非明顯的原因,您爲什麼使用單獨的索引來訪問該項目。您在for-each循環中已經準備了正確的物品... – dpr

+0

如果您發佈了[mcve] – xenteros

回答

2

使用for (Item item : items)是一個不錯的選擇。你爲什麼然後使用i?這個不成立。

我不知道你想達到的,但讓我告訴你下面的代碼是什麼:

public Item getItemByName(String name) { 
    for (Item item : items) { 
     if (item.getName().equals(name)) { 
      if (item instanceof HeadArmor) { 
       return item; 
      } 
     } 
    } 
    return null; 
} 

HeadArmor加入List<Item>不會成爲Item。它已經是Item。每個HeadArmorItemArmorHeadArmor。這也是一個Object。但是,List<Item>中的所有對象都保證爲Items(和Object),沒有別的。如果你想檢查它們是否也是ArmorHeadArmor你必須trycast。如果cast ing成功,則表示這個確定的iteminstance of HeadArmor

我假設你想要的東西可能是以下幾點:

Item i = getItemByName("helmet"); 
Header h = ((i == null) ? null : (HeadArmor)i); 
+1

你不應該使用控制邏輯的異常處理,這是一種不好的編碼習慣。改用'instanceof'。 –

+0

@PiotrWilkin你是對的。編輯。 – xenteros

+0

@PiotrWilkin複製我的答案建議? –

2

如果我用這個代碼將項目添加到列表中

items.add(new HeadArmor("helmet")); 
items.add(new Armor("chain mail")); 

,並嘗試以你的getItemByName方法檢索helmet。如預期的那樣,輸出將是HeadArmor。也許有創建和添加項目到項目列表的方式有問題嗎?!

0

可以使用方法instanceOf的檢查項目的類型是否爲headArmor與否