سؤال

I have an abstract Dice class and there are some concrete subclasses like SixFacesDice, TwentyFacesDice, etc... I want every Dice object to be comparable with an other but only if it is of the same subclass (e.g. a SixFacesDice can't be compared with a TwentyFacesDice) but I wouldn't to implement Comparable for every subclass.

The only way I see is to implement Comparable with Dice class and check if objects are of the same class, otherwise return 0. But this method is not elegant at all... Is there some method or design pattern to solve this?

هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

Elegant or not, comparing the result of getClass() is standard practice. Except that you shouldn't return 0 but instead throw a ClassCastException. Returning 0 does not signal "not comparable", but "equal", and that relation has certain constraints you cannot meet with that design, such as transitivity:

DiceA aLow, aHigh;
DiceB b;

In your case,

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

but

aLow.compareTo(aHigh) < 0
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top