2014-09-21 58 views
0

我正在設計問題,我必須設計一副牌。這裏是我的課怎麼看起來像解釋後面的編譯時錯誤wrt java泛型?

public interface ISuit { 
    String getLogo(); 
    String getName(); 
} 

public interface Icard<T extends ISuit> { 
    T getSuit(); 
    String getNumber(); 
} 

現在,我想寫一類爲每個13張牌,沿着這

public class Queen<E extends ISuit> implements Icard<E> { 
    @Override 
    public String getNumber() { 
     return "12"; 
    } 

    @Override 
    public E getSuit() { 
     return new E; 
    } 

} 

線的東西我打算創建女王的對象像這
1:Queen<Hearts> queenOfhearts = new Queen<Hearts>();

但是,對於我的皇后班,我有一個getSuit編譯時錯誤。我不知道什麼應該是getSuit的定義。這個功能應該是抽象的嗎?

+1

在設計中'Hearts'真的是它自己的類嗎?特別是對於排名和套裝,使用枚舉可能更有意義。 – 2014-09-21 08:19:11

+0

@SillyFreak我希望能夠在將來添加新的西裝。另外我正在學習面向對象的概念。 – Dude 2014-09-21 08:20:32

+0

這樣想:你需要'King'和'Queen'的類型安全嗎?就像你想要'Bike' vs'Car',或者你需要具有正確屬性的對象?如果是第二個,則使用兩個構造函數參數的'Card'類(如果您不想使用'enum')可能更有意義。 關於未來添加套裝,無論您是否爲每套套裝使用枚舉或自己的類,您都需要重新編譯代碼以添加新套裝。使每個訴訟只有一個對象可以讓你在運行時添加訴訟/不需要重新編譯。 – 2014-09-21 08:34:33

回答

1

在運行時,如果要實例化一個通用類型T,則必須具有Class<T>對象。

您可以更改getSuit(..)方法來簽名:

public E getSuit(Class<E> clazz); 

然後,實現將是:

public E getSuit(Class<E> clazz) { 
    try { 
     return clazz.newInstance(); 
    } catch (InstantiationException | IllegalAccessException e) { 
    // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    return null; 
} 

更妙的是,爲了擺脫對Class<T>參數方法,你可以將它傳遞給類的構造函數並將其保存到私有成員中。例如:

public class Queen<E extends ISuit> implements Icard<E> { 
    private Class<E> clazz; 

    public Queen(Class<E> clazz) { 
     this.clazz = clazz; 
    } 

    public String getNumber() { 
     return "12"; 
    } 

    public E getSuit() { 
     try { 
      return clazz.newInstance(); 
     } catch (InstantiationException | IllegalAccessException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return null; 
    } 
} 
+0

不是非常直觀或方便。如果你要使用類型參數,那麼最好使它們成爲構造函數的參數 – radai 2014-09-21 08:21:08

+0

當然,這只是一個提示。他應該改進設計。 – 2014-09-21 08:21:57

0

使Queen抽象類實現getNumber()。在派生類中執行getSuit(),如QueenHearts

0

首先,我相信你的如何去這個問題的想法是不正確從面向對象的方法。你想讓Card成爲一個具有兩個實例變量的類:數字和套裝。

然後,爲了擁有13張卡片中的每張卡片,您可以創建13個對象併爲其提供正確的卡號/套裝。例如,

Suit hearts = new Suit("Hearts"); 
Card queenHearts = new Card(12,hearts); 

至於編譯時錯誤背後的實際原因,請看Instantiating object of type parameter