2011-08-18 53 views
6

我试图创建一个通用的ArrayAdapter时遇到了问题。这可能与我对Java中泛型的有限理解有关,希望有人能够让我直观。基本上我有一个抽象基适配器类:与ArrayAdapter的泛型

public abstract class BaseAdapter<T> extends ArrayAdapter<T> 
{ 
    .... 
    private List<T> items; 
    .... 
    protected abstract List<T> build(JSONArray jsonArray); 
    .... 
    @Override 
    public T getItem(int position) 
    { 
     return items.get(position); 
    } 
    .... 
} 

然后我就扩展这个基类的适配器:

public class MyAdapter extends BaseAdapter<BaseModel> 
{ 
    .... 
    @Override 
    protected List<BaseModel> build(JSONArray jsonArray) 
    { 
     if (useBaseModel()) 
     { 
      return BaseModel.buildBaseModels(jsonArray); //returns List<BaseModel> 
     } 
     else 
     { 
      return SubclassModel.buildSubclassModels(jsonArray); //returns List<SubclassModel> 
     } 
    } 
    .... 
} 

该机型被定义为:

public class BaseModel{...} 

public class SubclassModel extends BaseModel{....} 

这不尽管SubclassModel扩展了BaseModel,但它们的列表并不等价。这个线程(Most efficient way to cast List<SubClass> to List<BaseClass>)解释为多,并表示要改用这一点:

List<? extends BaseModel> 

当我更改为:

public class MyAdapter extends BaseAdapter<? extends BaseModel> 
{ 
    ... 
    protected List<? extends BaseModel> build(JSONArray jsonArray) 
    ... 
} 

在构建方法的误差消失,但现在有一类说明: BaseAdapter中的getItem(int)与android.widget.ArrayAdapter中的getItem(int)发生冲突;试图使用不兼容的返回类型。

看起来好像getItem应该返回一个类型?扩展BaseModel,这是 - 任何人都可以建议?

谢谢!

回答

7

嗯,我的Java SDK甚至没有让我编

public class MyAdapter extends BaseAdapter<? extends BaseModel> 

,预计extends后无界类或接口。但是,这并不重要,你的问题的解决方案正在改变BaseAdapter类,如果这是一个选项:

public abstract class BaseAdapter<T> extends ArrayAdapter<T> 
{ 
    .... 
    private List<T> items; 
    .... 
    protected abstract List<? extends T> build(JSONArray jsonArray); 
    .... 
    @Override 
    public T getItem(int position) 
    { 
     return items.get(position); 
    } 
} 

然后

public class MyAdapter extends BaseAdapter<BaseModel> 
{ 
    ... 
    protected List<? extends BaseModel> build(JSONArray jsonArray) 
    ... 
} 

与以前的代码将工作。

编辑:

忘了解释为什么你的第一个解决方案没有奏效:

Language Spec

亚型不通过泛型类型扩展:T <:U并不意味着即C <:C

这意味着尽管SubclassModel扩展s的BaseModel,这并不意味着List扩展List。

+0

+1 ..Looks像我打字我的答案,而你正在张贴你的:-) – Kal

+0

类似的想法,类似的错误,类似的解决方案,这是可怕的:) – emboss

+0

果然 - 谢谢浮雕和Kal!我会检查第一个答案。 – user888867

0

我不能编译

public class MyAdapter extends BaseAdapter<? extends BaseModel> 

给了我一个错误说“A超可以不指定通配符”。

什么是对我的工作是这样的 -

public abstract class BaseAdapter<T> extends ArrayAdapter<T> 
{ 
    private List<? extends T> items; 
    protected abstract List<? extends T> build(JSONArray jsonArray); 
} 

public class MyAdapter extends BaseAdapter<BaseModel> 
{ 
    protected List<? extends BaseModel> build(JSONArray jsonArray); 
}