2013-06-17 3 views
0

Я беспокоюсь я сформулировал этот вопрос нет, так вот пример для иллюстрации:Наследования расширенного общего типа из интерфейса

У меня есть интерфейс:

public interface ICard extends Comparable<T>{ 

    public abstract String toString(); 

    public abstract int compareTo(T o) throws WrongCardTypeException; 

} 

То, что я хочу, что класс реализует Icard автомагически реализует Comparable<T> так что вы можете сравнить то, что класс реализует Icard

Вместо этого я должен указать общие для сопоставимого расширения и использовать вид instancof проверки ниже

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()); 
    } 

мне было интересно, если там было аккуратнее способ сделать это, что позволит мне избавиться от с в instanceof чеке? Wildcards? Я не уверен здесь. Или instanceof проверить нормально? Я слышал, что у него «запах кода», например. была плохая практика.


У меня аналогичная проблема с моим IDeck интерфейсом (?):

public interface IDeck<T extends ICard> extends Comparable<T>, Collection<T>{ 
    public ArrayList<T> getDeck(); 
    public void setDeck(Set<T> newDeck); 
} 

В классе, который реализует это, мой compareTo метод принимает параметры типа ICard, хотя я хочу, чтобы сравнить палуб, что наследовать от IDeck.

ответ

3

Вы можете сделать свой интерфейс ICard родовым, с границей, так это любой универсальный параметр типа должен сам быть ICard.

public interface ICard<T extends ICard<T>> extends Comparable<T>{ 

Затем вы можете указать PlayingCard в интерфейсе ICard в PlayingCard классе:

public class PlayingCard implements ICard<PlayingCard> { 
+0

Не могли бы вы говорить меня, почему я хочу 'Icard >'? Я думаю, что я использую использование подстановочных знаков, но я видел когда-либо только дженерики для сбора, и тот факт, что карты не являются коллекцией карт, отбрасывает меня. Далее, как я могу расширить это до интерфейса Deck, который может содержать только определенную карту? – Pureferret

+0

Вы заявили, что любой класс, реализующий «ICard», может сравнивать только «любой класс, реализующий ICard», следовательно, связанность. Дженерики - это когда класс имеет определенную, но неизвестную связь с другим классом. В коллекциях эта связь «содержит», но в вашем случае она «сопоставима с». Класс «Deck» звучит как набор карт, так что, как класс коллекций, вам может понадобиться нечто вроде «открытого интерфейса Deck >». – rgettman

+0

Спасибо. Я пробовал эту спецификацию интерфейса для своей «IDeck», но когда я расширяю Comparable, я получаю этот метод: «public int compareTo (PlayingCard o)», когда мне нужно «public int compareTo (PlayingCardDeck o)». Впрочем, стоит подумать, что стоит второй вопрос. – Pureferret

2

Я думаю, что вы хотите

public interface ICard<T> extends Comparable<T>{ 

    public abstract String toString(); 

    public abstract int compareTo(T o) throws WrongCardTypeException; 

} 

(обратите внимание на ICard<T>)

, а затем PlayingCard implements ICard<PlayingCard>.

Это говорит о том, что этот интерфейс не имеет ничего общего с интерфейсом Comparable, поскольку toString() уже доступен для всех объектов Java, и попытка его применения не будет иметь никакого эффекта.

1

Вы должны «повторно указать» T, попробуйте:

public interface ICard<T> extends Comparable<T>