如何在语义上不同时表示两个相等的枚举常量不相等?

时间:2016-04-10 18:15:17

标签: java enums override overloading equals

我目前正在开展一个井字游戏,我会跟踪细胞的情况。值使用State枚举。

protected static enum State {
    BLANK, X, O;

    @Override
    public String toString() {
        if (this.name().equals("BLANK"))
            return " ";
        else
            return this.name();
    }

    @Override
    public boolean equals(Object o2) {
        if (this == o2)
            return true;

        if (!(o2 instanceof State))
            return false;

        State state2 = (State)o2;
        if (state2.name().equals("BLANK"))
            return false;

        return this.name().equals(state2.name());
    }
};
然后,如果必要的单元格相等,则可以确定胜利者。问题是,如果单元格是BLANK," BLANK"会胜利的。我最初的想法是用上面的内容覆盖它,但这会产生编译错误,因为显然boolean equals(Object)在枚举中是最终的(我理解它是因为this article)。所以,我的下一个想法就是将其重载如下:

public boolean equals(State state2) {
    if (state2.name().equals("BLANK"))
        return false;

    return this.name().equals(state2.name());
}

但我们知道this won't work all the time,因为某些内容(如收藏集)只会查看equals(Object)签名。这里的问题是,在语义上,空白单元格根本不存在;那里什么都没有,所以应该没有什么比较可以与另一个空白单元相提并论。另一个类似的例子是,如果我有一个数字枚举:enum Sign { Positive, Negative, NaN }。将这两个数字相乘并找到结果符号的有效方法是(假装计算机当然没有处理过标志):

if (this.sign.equals(number2.sign))
    sign = Sign.Positive;
else
    sign = Sign.Negative;

未定义的数字无法共享符号,因为它们未定义!如果标志未定义并且在那时改变了东西,你可以随时检查以后看看,但这看起来非常倒退且效率低下,因为它仍然必须检查平等并做了很多工作已经徒劳无功。数量上的例子可以说只能与NaN相等,但我的观点是,它确实不准确,而且我确定还有很多其他的实例,其中两个枚举常数不会是#39在语义上是平等的,不会像那样工作,例如在我的tic-tac-toe示例中。在Java中处理这些情况有一种优雅的方式吗?

0 个答案:

没有答案