簡體   English   中英

子類和超類方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM