Assuming you want compile-time safety rather than just execution-time safety, you could use generics, like this:
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> {
}
That wouldn't stop someone from abusing it like this:
class BadDice extends Dice<Dice1>
... but when used properly, I think it gives you the behaviour you want.
Note that this only works with one inheritance level, too - you wouldn't be able to cleanly have a subclass of a subclass of Dice<T>
, because then your "same class" enforcement would fail.
If you're fine with just execution-time safety, then comparing this.getClass()
with other.getClass()
is absolutely reasonable.