簡體   English   中英

在這種情況下如何避免類型檢查

[英]How can I avoid typechecking in this situation

情況如下:

我們有一個游戲,里面有玩家和物品。 當玩家在他們的庫存中擁有所有 3 個特定物品並組裝它們(地圖上每個物品只有 1 個)時,游戲就獲勝了。 物品有一個非常簡單的界面,玩家可以對它們調用use() 還有其他實現Item接口的類已被排除在代碼段之外。 如果我要忽略基本的 OOP 原則,我只能說當玩家使用其中之一時,我們會遍歷玩家的庫存並檢查所有這三種特定類型的物品是否都在其中。 我如何避免這樣做?

public interface Item{
    public void use();
}

public class SpecificItem1 implements Item{
    public void use(){...}
}

public class SpecificItem2 implements Item{
    public void use(){...}
}

public class SpecificItem3 implements Item{
    public void use(){...}
}

public class Player{

    ArrayList<Item> inventory;

    public void didWeWin() {

        int numOfSItems = 0;

        for(Item i : inventory) {
            if(i instanceOf SpecificItem1)
                numOfSItems++;
            if(i instanceOf SpecificItem2)
                numOfSItems++;
            if(i instanceOf SpecificItem3)
                numOfSItems++;
        }

        if(numOfSItems == 3)
            win();
    }

}

您可以使用getClass()獲取項目的類,然后計算唯一類的數量:

public void didWeWin() {
   if (inventory.stream().map(Object::getClass).distinct().count() == 3L) {
       win();
   }
}

如果庫存可能包含不屬於獲勝條件的其他種類的物品,檢查至少有三種不同的物品是不夠的。 在這種情況下,您可以使用containsAll方法檢查獲勝條件所需的項目類。

// List.of works in Java 9+, use Arrays.asList for Java 8
private static List<Class<?>> WIN_CONDITION
    = List.of(SpecificItem1.class, SpecificItem2.class, SpecificItem3.class);

public boolean hasWon() {
    return inventory.stream()
        .map(Object::getClass)
        .collect(Collectors.toSet())
        .containsAll(WIN_CONDITION);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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