2011-08-18 4 views
6

제네릭 ArrayAdapter를 만드는 동안 문제가 발생했습니다. Java에서 제네릭에 대한 제 제한적 이해와 관련이있을 것입니다. 이하지 않는ArrayAdapters를 사용하는 Generics

public class BaseModel{...} 

public class SubclassModel extends BaseModel{....} 

:로

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 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); 
    } 
    .... 
} 

나는이 기본 클래스를 확장 어댑터있다 : 기본적으로 나는 추상 기본 어댑터 클래스가 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

흠, 내 자바 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) 
    ... 
} 

작동합니다 앞의 코드와 함께.

편집 :

첫 번째 솔루션이 작동하지 않은 이유를 설명 잊으 : T <을 :

Language Spec

하위 유형이 제네릭 형식을 통해 연장하지 않는다고 말했습니다 U는 의미하지 않는다 그 C < : C.

이것은 SubclassModel extend BaseModel은 List가 List를 확장한다는 것을 의미하지 않습니다.

+0

1 ..Looks 당신이 – Kal

+0

비슷한 생각 :-) 당신을 게시하는 동안 나는 내 대답을 입력 것처럼 , 유사한 오류, 유사한 해결책, 그게 무서운 :) – emboss

+0

물론 - 감사 양각과 칼! 첫 번째 대답을 확인하겠습니다. – user888867

0

나는

public class MyAdapter extends BaseAdapter<? extends BaseModel> 

나에게 "슈퍼 와일드 카드를 지정 할 수 없습니다"라는 오류를 제공 컴파일 할 수 없습니다.나를위한 일이이다 무엇

-

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); 
}