繁体   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