Reputation: 7608
I'm worried I've phrased this question wrongly, so here is an example to illustrate:
I have an interface:
public interface ICard extends Comparable<T>{
public abstract String toString();
public abstract int compareTo(T o) throws WrongCardTypeException;
}
What I want is that the class implementing ICard automagically implements Comparable<T>
so that you can only compare whatever class implements ICard
Instead I need to specify the generic for the comparable extension and use the sort of instancof
check below
public interface ICard extends Comparable<ICard>{
public abstract String toString();
public abstract int compareTo(ICard o) throws WrongCardTypeException;
}
public class PlayingCard implements ICard{
public enum Rank { TWO, THREE, FOUR, FIVE, SIX,
SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE }
public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES }
private Rank rank;
private Suit suit;
public PlayingCard(Rank rank, Suit suit) {
this.rank = rank;
this.suit = suit;
}
public Rank getRank() { return rank; }
public Suit getSuit() { return suit; }
@Override
public String toString() { return rank + " of " + suit; }
@Override
public int compareTo(ICard o) throws WrongCardTypeException {
if (o instanceof PlayingCard){
PlayingCard c = (PlayingCard)o;
int rankCompare = rank.compareTo(c.rank);
return rankCompare != 0 ? rankCompare : suit.compareTo(c.suit);
}
throw new WrongCardTypeException("Tried to compare "+o.getClass().getCanonicalName()+" to "+ this.getClass().getCanonicalName());
}
I was wondering if there was a neater way to do this that would let me do away with the the instanceof
check? Wildcards? I'm not sure here. Or is the instanceof
check ok? I've heard it has 'code smell', e.g. was bad practice.
I have a similar (?) issue with my IDeck interface:
public interface IDeck<T extends ICard> extends Comparable<T>, Collection<T>{
public ArrayList<T> getDeck();
public void setDeck(Set<T> newDeck);
}
In the class that implements this, my compareTo
method takes parameters of type ICard
, though I want to compare decks that inherit from IDeck.
Upvotes: 0
Views: 124
Reputation: 1778
You need to "re-specify" T, try with:
public interface ICard<T> extends Comparable<T>
Upvotes: 1
Reputation: 178253
You can make your ICard
interface generic, with a bound, so it any generic type parameter must itself be an ICard
.
public interface ICard<T extends ICard<T>> extends Comparable<T>{
Then you can specify PlayingCard
in the ICard
interface in the PlayingCard
class:
public class PlayingCard implements ICard<PlayingCard> {
Upvotes: 3
Reputation: 198033
I think you want
public interface ICard<T> extends Comparable<T>{
public abstract String toString();
public abstract int compareTo(T o) throws WrongCardTypeException;
}
(note the ICard<T>
)
and then PlayingCard implements ICard<PlayingCard>
.
That said, this interface gets you exactly nothing over the Comparable
interface, since toString()
is already available for all Java objects, and trying to require it will have no effect.
Upvotes: 2