Java:使子类仅与相同的子类相比较

Java:使子类仅与相同的子类相比较,java,subclass,comparable,Java,Subclass,Comparable,我有一个抽象的骰子类,有一些具体的子类,比如SixFacesDice,TwentyFacesDice,等等。。。我希望每个骰子对象都可以与其他对象进行比较,但前提是它属于相同的子类(例如,一个SixFacesDice不能与一个TwentyFacesDice进行比较),但我不会为每个子类实现可比较 我看到的唯一方法是实现Comparable with Dice类并检查对象是否属于同一类,否则返回0。但是这种方法一点也不优雅。。。有什么方法或设计模式可以解决这个问题吗?假设您想要编译时安全而不仅仅是

我有一个抽象的骰子类,有一些具体的子类,比如SixFacesDice,TwentyFacesDice,等等。。。我希望每个骰子对象都可以与其他对象进行比较,但前提是它属于相同的子类(例如,一个SixFacesDice不能与一个TwentyFacesDice进行比较),但我不会为每个子类实现可比较

我看到的唯一方法是实现Comparable with Dice类并检查对象是否属于同一类,否则返回0。但是这种方法一点也不优雅。。。有什么方法或设计模式可以解决这个问题吗?

假设您想要编译时安全而不仅仅是执行时安全,您可以使用泛型,如下所示:

abstract class Dice<T extends Dice> implements Comparable<T> {
    int value;

    public int compareTo(T other) {
        return Integer.compare(value, other.value);
    }
}

final class Dice1 extends Dice<Dice1> {
}

final class Dice2 extends Dice<Dice2> {
}
class BadDice extends Dice<Dice1>
抽象类Dice实现了可比较的{
int值;
公共int比较(T其他){
返回整数.compare(value,other.value);
}
}
最后一类骰子1扩展骰子{
}
最后一类骰子2扩展骰子{
}
这并不能阻止有人这样滥用它:

abstract class Dice<T extends Dice> implements Comparable<T> {
    int value;

    public int compareTo(T other) {
        return Integer.compare(value, other.value);
    }
}

final class Dice1 extends Dice<Dice1> {
}

final class Dice2 extends Dice<Dice2> {
}
class BadDice extends Dice<Dice1>
class BadDice扩展了骰子
。。。但是如果使用得当,我想它会给你想要的行为

请注意,这也只适用于一个继承级别-您将无法干净地拥有
Dice
子类的子类,因为这样您的“同一类”强制将失败

如果您对执行时安全性没有意见,那么将
this.getClass()
other.getClass()
进行比较是绝对合理的。

假设您想要的是编译时安全性而不仅仅是执行时安全性,那么可以使用泛型,如下所示:

abstract class Dice<T extends Dice> implements Comparable<T> {
    int value;

    public int compareTo(T other) {
        return Integer.compare(value, other.value);
    }
}

final class Dice1 extends Dice<Dice1> {
}

final class Dice2 extends Dice<Dice2> {
}
class BadDice extends Dice<Dice1>
抽象类Dice实现了可比较的{
int值;
公共int比较(T其他){
返回整数.compare(value,other.value);
}
}
最后一类骰子1扩展骰子{
}
最后一类骰子2扩展骰子{
}
这并不能阻止有人这样滥用它:

abstract class Dice<T extends Dice> implements Comparable<T> {
    int value;

    public int compareTo(T other) {
        return Integer.compare(value, other.value);
    }
}

final class Dice1 extends Dice<Dice1> {
}

final class Dice2 extends Dice<Dice2> {
}
class BadDice extends Dice<Dice1>
class BadDice扩展了骰子
。。。但是如果使用得当,我想它会给你想要的行为

请注意,这也只适用于一个继承级别-您将无法干净地拥有
Dice
子类的子类,因为这样您的“同一类”强制将失败


如果您对执行时间安全性没有问题,那么将
this.getClass()
other.getClass()
进行比较是绝对合理的。

无论是否优雅,比较
getClass()
的结果都是标准做法。除了不应返回0,而应抛出一个
ClassCastException
。返回0并不表示“不可比较”,而是表示“相等”,并且该关系具有该设计无法满足的某些约束,例如传递性:

就你而言

aLow.compareTo(b) == b.compareTo(aHigh) == 0
但是

aLow.compareTo(aHigh)<0

优雅与否,比较
getClass()的结果是标准做法。除了不应返回0,而应抛出一个
ClassCastException
。返回0并不表示“不可比较”,而是表示“相等”,并且该关系具有该设计无法满足的某些约束,例如传递性:

就你而言

aLow.compareTo(b) == b.compareTo(aHigh) == 0
但是

aLow.compareTo(aHigh)<0

你为什么说这“一点也不优雅”?这是正确的做法。这不仅确保了每个使用骰子与另一个骰子进行比较的人都会强制你比较骰子的方式,而且只要他们使用基于骰子超类的子类,你的比较方式就不能改变。当然,您需要将compare方法设置为final,这样它就不会被忽略。或者,你可以考虑实现一个可比较的,但实际上不会强制执行任何东西。我怀疑OP想要的是编译时安全,而不仅仅是执行时安全。因为所有不同类型的骰子都需要比较。。。但是,另一方面,不同类型的骰子完全没有顺序。那么,是的,也没那么糟糕:)这个比较实际上意味着什么?一个六面模具如何大于或小于另一个?为什么你说这“一点都不优雅”?这是正确的方法。这不仅确保了每个使用骰子与另一个骰子进行比较的人都会强制你比较骰子的方式,而且只要他们使用基于骰子超类的子类,你的比较方式就不能改变。当然,您需要将compare方法设置为final,这样它就不会被忽略。或者,你可以考虑实现一个可比较的,但实际上不会强制执行任何东西。我怀疑OP想要的是编译时安全,而不仅仅是执行时安全。因为所有不同类型的骰子都需要比较。。。但是,另一方面,不同类型的骰子完全没有顺序。那么,是的,也没那么糟糕:)这个比较实际上意味着什么?一个6面骰子如何大于或小于另一个?OP可能有一个
集合
,其中将包含异构骰子实例。我不认为泛型药有帮助。@Jon Skeet是的,你是对的。但我这样讨论是因为我需要不止一个层次的继承…@user2691583:如果你想到了方法并放弃了它们,那么你应该在问题中说明这一点,以避免浪费人们的时间。@MarkoTopolnik:不幸的是,我们没有足够的上下文来了解这一点。。。OP的评论表明他们确实需要编译时安全性,但这有点模糊。“否则返回0”-在我看来,这意味着运行时检查。OP可能会有一个
集合
,其中将包含异构dice实例。我不认为泛型药有帮助。@Jon Skeet是的,你是对的。但我这样讨论是因为我需要不止一个层次的继承…@user2691583:如果你想到了方法并放弃了它们,那么你应该在问题中说明这一点,以避免浪费人们的时间。@MarkoTopolnik:不幸的是,我们没有足够的上下文来了解这一点。。。OP的评论表明他们确实想要康比