[英]Subclass and Superclass methods
我正在創建具有不同類型正方形的壟斷游戲。 Square
是父類 , PropertySquare
是子類 。
我創建了一個循環,擲骰子並將玩家移到另一個正方形。 這些正方形在數組列表中,我可以在它們上調用超類方法。 但是,即使將正方形設置為更特定的類型(正方形的子類),我也無法在它們上調用子類方法。
這就是我在董事會課程中初始化正方形的方式。
private static final ArrayList<Square> squares = new ArrayList<Square>(40);
squares.add(1, new PropertySquare("Old Kent Road", 1, 60, "Brown"));
board.getSquare(pos).getName());
getName
是超類正方形中的方法。 但是,即使正方形是屬性類型,也無法調用PropertySquare
類中的方法,例如getPrice();
我將如何更改它或能夠調用子類方法?
我假設board.getSquare()
返回一個Square
,而Square
沒有任何getPrice()
方法,因此即使實例實際上是一個PropertySquare
(aka 多態性 getPrice()
,也不能在聲明為Square
的對象上調用getPrice()
)。 為此,您必須首先轉換為特定的子類。 例如:
final Square square = board.getSquare(pos);
if (square instanceof PropertySquare) {
((PropertySquare)square).getPrice();
}
NB:我要從更一般的意義上回答這個問題,我意識到並不是所有的壟斷廣場都有價格……但是,代碼本身的問題可以通過兩種方式解決。
如果所有商品都有價格,則可能要使用“抽象”基類。
然后,您將超類中的方法放入:
protected abstract int getPrice();
並在您的子類中實現它。
因此,您可能擁有諸如undevelopedSquare,propertySquare,gardenSquare等子類。
但是,對於Monopoly,如果只有propertySquare實例具有getPrice,則應使用
if (square instanceOf PropertySquare) {
price = ((PropertySquare)square).getPrice();
}
NB2:您還擁有“公用事業廣場”,例如Waterworks,它的價格旁邊會有不同的屬性(即使您可以購買,也無法在公用事業上建造酒店)。
因此,在這種情況下,接口可能更合適,例如:
interface PlayableSquare -> Generic square things, you can land on one for instance
interface SaleableSquare -> has pricing etc
interface BuildableSquare -> can build hotels
然后將您的通用
private static final ArrayList<? extends Square> squares
然后,PropertySquare將是:
public class PropertySquare extends AbstractSquare implements SaleableSquare, BuildableSquare
其中Abstract類實現了“ PlayableSquare”。 盡管那可能只是一步,因為它幾乎只是標記界面。
您可以使用instanceOf來檢查每個接口的實現,即,某個Utility是否具有您希望調用的其他方法。
您應該將泛型與ArrayList一起使用。 如果您的列表僅包含PropertySquare
類型,請執行以下操作:
private static final ArrayList<PropertySquare> squares = new ArrayList<>(40);
squares.add(1, new PropertySquare("Old Kent Road", 1, 60, "Brown"));
然后,列表將返回PropertySquare
類型的對象。
如果列表可以包含任何類型的正方形,請執行以下操作:
private static final ArrayList<Square> squares = new ArrayList<>(40);
squares.add(1, new PropertySquare("Old Kent Road", 1, 60, "Brown"));
Square sq = squares.get(0);
if(sq instanceof PropertySquare){
PropertySquare pSq = (PropertySquare) sq;
//now you can use any method of PropertySquare
}
您的代碼中的問題是您的對象屬於Square類型,並且對任何子類的方法一無所知。 因此,您必須進行類型轉換。
您可以通過一組ifs處理着陸廣場:
if (square instanceof PropertySquare) {
((PropertySquare)square).getPrice();
}else if(square instanceof PrisonSquare) {
//do nothing
}//etc..
您聲明的ArrayList
綁定到Square
這意味着在與任何項目進行交互時,盡管它是子類的實例,但您將擁有Square
對象的集合和Square
引用。 這稱為多態性。
由於引用是Square
類型的事實,因此Java知道的唯一方法是那些在Square
聲明的方法以及任何其他繼承的方法。 為了能夠調用子類的方法,您需要檢查引用是否指向PropertySquare
的實例,然后將引用向下轉換為PropertySquare
。 您是說,沒關系,我知道它是PropertySquare
一個實例,因此我可以安全地調用PropertySquare
聲明的getPrice()
方法。
if (square instanceof PropertySquare) {
((PropertySquare)square).getPrice();
}
或者,您可以查看實例的類名稱:
square.getClass().getSimpleName(); // Would just give you PropertySquare
square.getClass().getCanonicalName(); // Would give you the fully qualified name e.g. com.foo.bar.PropertySquare
有關更多信息:
https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.