2013-08-28 59 views
1

我的目標非常簡單。我有一個SetInterface<T>Java - 泛型通配符問題

public interface SetInterface<T> 
{ 
    public T duplicateSet(); 
} 

然後我也有一個ExerciseInterface <T extends SetInterface<?>>

public interface ExerciseInterface <T extends SetInterface<?>> 
{ 
    public T getSet(int pos); 
    public void addSet(T set); 
} 

一切都很正常了這一點。

問題來了,我嘗試創建一個包含所有實現ExerciseInterface的不同類的泛型集合。

我對泛型相當陌生,我一直在想我已經解決了一些問題,但我所做的只是推動錯誤。

問題是由我addA()addB()方法

public class Workout { 

    private String name; 
    private List <? extends ExerciseInterface<SetInterface<?>>> exerciseList; 

// Constructor 
public Workout(String name) 
{ 
    this.name = name; 
    exerciseList = new ArrayList<ExerciseInterface<SetInterface<?>>>(); 
} 

public String getName() { 
     return name; 
    } 

public void setName(String name) { 
     this.name = name; 
    } 

public void addExerciseA(ExerciseInterface<SetInterface<?>> exercise { 
     exerciseList.add(exercise); 
    } 

public <T extends ExerciseInterface<SetInterface<?>>> void addExerciseB(T exercise { 
     exerciseList.add(exercise); 
    } 

public ExerciseInterface<SetInterface<?>> getExercise(int pos) { 
     return exerciseList.get(pos); 
    } 
} 

第一add()提供了以下錯誤相當多總結..

The method add(capture#2-of ? extends ExerciseInterface<SetInterface<?>>) in the type List<capture#2-of ? extends ExerciseInterface<SetInterface<?>>> is not applicable for the arguments (ExerciseInterface<SetInterface<?>>) 

第二add()給出了這樣的錯誤..

The method add(capture#2-of ? extends ExerciseInterface<SetInterface<?>>) in the type List<capture#2-of ? extends ExerciseInterface<SetInterface<?>>> is not applicable for the arguments (ExerciseInterface<SetInterface<?>>) 

只是爲了率,我有一個SetInterface不同類型的集合實現。

我也有不同的練習鏡像集。例如:

BodyWeightExercise implements <SetInterface<BodyweightSet>> 

WeightsExercise implements <SetInterface<WeightsSet>> 

所以我的目標是有不同的練習徵收,讓我添加到集合的方法。

任何幫助將受到真誠的讚賞,我已經失去了一些頭髮。

乾杯。

編輯:如果這是不可行的任何指針在一個更可行的方向將不勝感激。

EDIT2:我將列表更改爲List <ExerciseInterface<SetInterface<?>>> exerciseList;,並且add()方法上的錯誤都消失了。

但是,使用這種測試代碼..

WeightsSet weightsSet = new WeightsSet();  
WeightsExercise weightsExercise = new WeightsExercise(); 

weightsExercise.addSet(weightsSet); 

Workout workout = new Workout("Wok"); 
workout.addExerciseA(weightsExercise);  <-- ERROR 

我想一個WeightsExercise增加鍛鍊的名單,但現在我得到這個錯誤..

Bound mismatch: The generic method addExerciseB(T) of type Workout is not applicable for the arguments (WeightsExercise). The inferred type WeightsExercise is not a valid substitute for the bounded parameter <T extends ExerciseInterface<SetInterface<?>>> 

EDIT 3:(以上以及混凝土的方法更新的接口)上延伸ExerciseInterface和SetInterface實施例類

public class WeightsExercise implements ExerciseInterface<SetInterface<WeightsSet>> 
{ 
@Override 
public SetInterface<WeightsSet> getSet(int pos) {return null;} 

@Override 
public void addSet(SetInterface<WeightsSet> set) {} 
} 

public class WeightsSet implements SetInterface<WeightsSet> 
{ 
@Override 
public WeightsSet duplicateSet() {return null;} 
} 

解決:該解決方案似乎正常涵蓋一切。

public class Workout 
{ 
private String name; 
private List <ExerciseInterface<? extends SetInterface<?>>> exerciseList; 

// Constructor 
public Workout(String name) 
{ 
    this.name = name; 
    exerciseList = new ArrayList<ExerciseInterface<? extends SetInterface<?>>>(); 
} 

public String getName()                   {return name;} 
public void setName(String name)                {this.name = name;} 
public void addExerciseA(ExerciseInterface<? extends SetInterface<?>> exercise)     {exerciseList.add(exercise);} 
public ExerciseInterface<? extends SetInterface<?>> getExercise(int pos)      {return exerciseList.get(pos);} 

}

+0

您不能增加一些你不知道的類型。 –

+0

所以你會有一個關於如何獲得一個包含一系列擴展ExerciseInterface 的類的集合的建議? – mgibson

+0

你需要向我們展示你的課程是怎樣的。 'WeigthsSet','WeightsExercise'。目前尚不清楚。 –

回答

2

你應該改變你的列表聲明:

List<ExerciseInterface<SetInterface<?>>> exerciseList; 

當你使用上界通配符,我不認爲你真的需要在這裏,你可以不加除了null以及之前從其中獲取的元素之外,列表中的任何內容。

這是因爲,你不確切知道它實際引用的具體參數化列表類型。例如:List<? extends CharSequence>可以參考ArrayList<String>ArrayList<StringBuffer>。所以,你不能添加任何東西到這個列表中,因爲它不是類型安全的。您可能正在將StringBuffer對象添加到ArrayList<String>,這會在運行時失敗。


更新後:

我猜你要創建一個parallel class hierarchy,並且在弄亂。也許,你想你的ExerciseInterface的樣子:

// Notice the use of `T` in `SetInterface<T>` instead of `SetInterface<?>` 
interface ExerciseInterface<T extends SetInterface<T>> { 
    SetInterface<T> getSet(int pos); 
    void addSet(SetInterface<T> set); 
} 

,然後你WeightsExercise類將被修改,例如:

class WeightsExercise implements ExerciseInterface<WeightsSet> { 
    @Override 
    public SetInterface<WeightsSet> getSet(int pos) {return null;} 

    @Override 
    public void addSet(SetInterface<WeightsSet> set) {} 
} 

您還需要使你的Workout類一般是這樣的:

public class Workout<U extends SetInterface<U>, T extends ExerciseInterface<U>> { 

} 

然後在您的中將所有出現的ExerciseInterface<SetInterface<?>>替換爲類。

,創造Workout這樣的實例:

Workout<WeightsSet, WeightsExercise> workout = new Workout<>("Wok"); 
workout.addExerciseA(weightsExercise); 

這將是什麼做出正確的設計海事組織。


推薦崗位:

參考文獻:

+0

乾杯Rohit,我會把它放在船上。我也一直在閱讀其中一些資源,但我會進一步研究。儘管我拿出了上界有界的通配符,但現在有一個不同的通用相關問題。請參閱編輯2 – mgibson

+0

將盡快檢查。感謝您的時間 – mgibson

+0

嗯羅希特,似乎有一些偉大的東西在那裏。但是,我試圖實現的是能夠將WeightsSet和WeightsExercise添加到鍛鍊是,但也是另一個實現ExerciseInterace的練習。 – mgibson