2011-08-18 65 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); 
}