2011-11-13 55 views
2

中調用方法我目前正在開展一些學校項目;我們正在開發一個簡單的RPG,但我似乎在質疑我的一些Java代碼。不能在類

我有一個Abstract類稱爲Item,那我也ArmorWeapon類,其無論從Item繼承。 ArmorWeapon都具有Item不具有的一些屬性。

所以在我的數據庫的包裝,我有一個loaditem方法,後者的統計數據,並創建我的類的實例(閱讀代碼中的註釋):

public Item loadItem(int itemID) 
{ 
    // Setting item, as a Item, as it can be both Weapon or Armor 
    Item item; 

    try { 

     // Build prepared statement 
     PreparedStatement stmt = con.prepareStatement("SELECT * FROM item WHERE iid = ?"); 

     // Set Parameter 
     stmt.setInt(1, itemID); 

     // Execute the query 
     ResultSet rs = stmt.executeQuery(); 

     // Get row 
     rs.first(); 

     // Set all values and keys 


     if(rs.getString("type").equals("weapon")) { 
      item = new Weapon(); 
      // SetDamage is unique to Weapon, and setDefense to armor 
      item.setDamage(); 
     }else { 
      item = new Armor(); 
      item.setDefense() 
     } 

     item.setIid(rs.getInt("iid")); 
     item.setName(rs.getString("name")); 
     item.setDescription(rs.getString("description")); 
     item.setSellValue(rs.getInt("sellvalue")); 
     item.setBuyValue(rs.getInt("buyvalue")); 
     item.setStrength(rs.getInt("strength")); 
     item.setAgility(rs.getInt("agility")); 
     item.setEndurance(rs.getInt("endurance")); 

我沒有問題設置的Weapon一個實例或Armor,但它無法找到類中的方法。

我是否真的需要創建武器和裝甲物體,並在返回後輸入?

回答

3

是的,如果您打算調用實例方法,則方法調用的「目標」表達式必須具有已知具有適當方法的編譯時間類型。編譯器需要在編譯時間上解析方法調用。 (任何重載解析都是在編譯時完成的;實際的實現是在執行時根據多態性決定的。)

目前還不清楚爲什麼您想要item變量擺在首位。這聽起來像你應該有:

if (rs.getString("type").equals("weapon")) { 
    Weapon weapon = new Weapon(); 
    weapon.setDamage(); 
    return weapon; 
} else { 
    Armor armor = new Armor(); 
    armor.setDefense(); 
    return armor; 
} 

這是假設你想立即返回 - 你的代碼被截斷,所以它不清楚。如果你真的需要item變量,你可以只分配weaponarmoritem其中我有上面的返回語句。

編輯:聽起來好像是這樣的話,所以你必須:

// I'd still declare `item` as late as possible, i.e. here rather than 
// outside the `try` block, unless you *also* need it outside the try block... 
Item item; 
if (rs.getString("type").equals("weapon")) { 
    Weapon weapon = new Weapon(); 
    weapon.setDamage(); 
    item = weapon; 
} else { 
    Armor armor = new Armor(); 
    armor.setDefense(); 
    item = armor; 
} 
// Other code using `item` here 

事實上,你可能希望把代碼給武器初始化到一個單獨的方法。然後,你可以使用:

String type = rs.getString("type"); 
Item item = type.equals("weapon")) ? createWeapon() : createArmor(); 
+0

@Downvoter:護理評論? –

+0

因爲如果我在if裏創建一個實例,我只能在那裏使用它。該項目本身有大量的統計數據,所以如果我使用你的例子,我將不得不在if和else中寫入10個setter。這似乎很愚蠢,但如果沒有辦法。 :) – MartinElvar

+0

@MartinElvarJensen:好吧,如果你真的*在if語句後面顯示*其他代碼使用'item',我會以不同的方式寫出答案。我猜不出你既沒有顯示也沒有描述的代碼! –

3

你可以這樣說:

if (...) { 
     Weapon w = new Weapon(); 
     // SetDamage is unique to Weapon, and setDefense to armor 
     w.setDamage(); 
     item = w; 
    } else { 
     ... 
    } 

if塊/序列後,您可以使用item你回來之前。但你只能調用Item類的方法。同樣,您的loadItem方法的調用者只能使用Item類中的方法對您返回的值進行處理,除非他們仔細使用了強制轉換。

0

爲了調用獨特的「武器」,你必須將項目指針轉換爲武器,這樣的方法:

Weapon weaponPointer = (Weapon)item; 
weaponPointer.setDamage(); 
+0

鑑於它是在前一行中構建的,因此不需要在此處投射 - 只需使用單獨的變量即可。 –

+0

確實如此,但它適用於一般情況,其他則不適用。 –

0

項目=新武器()將項目交給一個武器實例,但項目會不能成爲武器,以指代的裝甲武器的方法,你可以做以下之一:

if (rs.getString("type").equals("weapon")) { 
    Weapon weapon = new Weapon(); 
    weapon.setDamage(); 
    return weapon; 
} else { 
    Armor armor = new Armor(); 
    armor.setDefense(); 
    return armor; 

}

if (rs.getString("type").equals("weapon")) { 
item = new Weapon(); 
((Weapon)item).setDamage(); 
} else { 
item = new Armor(); 
((Armor)item).setDefense(); 
} 

退貨項目

+0

那麼你是否真的在第二個例子中鑄造它? – MartinElvar

+0

是的,我正在鑄造它 – mprabhat

0

你應該區分實例類型和引用類型;

Item myItem = new Weapon(); 

實例類型:武器 參考類型:項目

所以,如果你調用一個方法上myItem它只能是項目類的方法。因爲您的參考類型是Item。

在你的情況下,你想調用一個武器的方法,所以你的參考類型也必須是武器。

Weapon myWeapon = new Weapon(); 
item.setDamage(); // method of Weapon class, it's ok 

注意引用類型和實例類型!

我想這個答案是最好的:(感謝喬恩斯基特)

// I'd still declare `item` as late as possible, i.e. here rather than 
// outside the `try` block, unless you *also* need it outside the try block... 
Item item; 
if (rs.getString("type").equals("weapon")) { 
    Weapon weapon = new Weapon(); 
    weapon.setDamage(); 
    item = weapon; 
} else { 
    Armor armor = new Armor(); 
    armor.setDefense(); 
    item = armor; 
} 
// Other code using `item` here