2013-08-28 61 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