2015-02-01 3 views
0

Android 앱에 어댑터가 있는데 Generic으로 만들고 싶습니다. 방법은 DataTypeC 매개 변수를 받아야 할 때 내가 다른 오류를 받고 있어요 내가 그것을 매개 변수 유형을 통과Java에서 제네릭을 사용하도록 사용자 지정 어댑터를 변환하십시오.

public class myAdapter extends FragmentStatePagerAdapter { 

DataTypaA myFragment; 
DataTypeB data; 
DataTypeC items; 

public myAdapter(FragmentManager fm, DataTypaA fragment) { 
     data = new SparseArray<DataTypeB>(); 
     myFragment = fragment; 
     items = myFragment.getData(); 
    } 

    public DataTypeB getItem(int position) { 
     return data.get(position); 
    } 

    @Override 
    public int getCount() { 
     return items.getList().size(); 
    } 


public void setData() { 

items = myFragment.getItems() //getItems return DataTypeC 
data.setTheData (items) 
} 
} 

내가 일반적인

public class myAdapter <A,B,C> extends FragmentStatePagerAdapter { 

A myFragment; 
B data; 
C items; 

public myAdapter(FragmentManager fm, A fragment) { 
     data = new SparseArray<B>(); 
     myFragment = fragment; 
     items = (C) myFragment.getData(); 
    } 

    public B getItem(int position) { 
     return data.get(position); 
    } 

    @Override 
    public int getCount() { 
     return items.getList().size(); 
    } 


public void setData() { 

items = myFragment.getItems() //getItems return DataTypeC 
data.setTheData (items) 
} 
} 

로 변경되었지만 :

Basiclly 어댑터는 같다 C (data.setTheData (items))은 실제로 형식이 DataTypeC이고 CDataTypeC으로 변환합니다. 그리고 getCount()에서 itemsDataTypeC으로 변환하는 중 오류가 발생했습니다.

예를 들어 getItem을 오버라이드하려고 할 때 실수가 발생하지만 동일한 이름의 메소드를 만들면 컴파일됩니다.

//Error - "The return type is incompatible with FragmentStatePagerAdapter.getItem(int)" 
@Override 
    public B getItem(int position) { 
     return (B) data.get(position); 
    } 

//compiles 
    public B getItemTest(int position) { 
     return data.get(position); 
    } 

모든 아이디어를 어떻게 수정하여 100 % 일반일까요?

추가 : 나는 물론 <T>의 실행 및 <C>가 동일한 경우

public class TypeA <T> { 
    private T mData; 

     public T getData() { return mData;; } 
    } 



    public class myAdapter <A,B,C> extends FragmentStatePagerAdapter { 

     A myFragment; 
     B data; 
     C items; 

     public myAdapter(FragmentManager fm, A fragment) { 
       data = new SparseArray<B>(); 
       myFragment = fragment; 
       items = myFragment.getData(); //Error - The method getData() is undefined for the type T 
      } 

} 

내가 ... 오류를 컴파일 받고 있어요 : 당신의 대답 나는 변경 후에는 제네릭 형식의 복귀를 지원하기 위해 유형. "genericizing"클래스, 당신은 제네릭에 의해 genericized 유형의 모든 인스턴스를 교체해야

+1

왜 당신이 일반적인 만들고 싶어합니까 : 나는 가짜 클래스를 사용이를 위해

class myAdapter <A extends DataTypaA<C>, B extends SparseArray<? extends DataTypeB, ? extends DataTypeC>, C extends DataTypeC> extends FragmentStatePagerAdapter { A myFragment; SparseArray<B, C> data; C items; public myAdapter(FragmentManager fm, A fragment) { data = new SparseArray<B, C>(); myFragment = fragment; items = myFragment.getData(); } public B getItem(int position) { return data.get(position); } @Override public int getCount() { return items.getList().size(); } public void setData() { items = myFragment.getItems(); //getItems return DataTypeC data.setTheData(items); } } 

: 최종 구현 과 같이 갈 수있다? 유스 케이스를 제공 할 수 있습니까? 달성하고자하는 것은 분명하지 않습니다 (또는 적어도 저에게) :'data'는'DataTypeB' 또는'SparseArray ' 타입입니까? – Matthieu

+0

@Matthieu'data'는 타입'B'입니다. 실수였습니다, 고마워요 ...이 어댑터는 다른 클래스에 그것의 사용법을 알려주고 싶다면' '코드를 복사하고 새 어댑터를 만들지 않습니다. –

+2

Alex, 게시하기 전에 코드가 의미 있는지 확인해야합니다. 비 제너릭 코드는 전혀 컴파일되지 않으므로 현명한 권고를하기가 어렵습니다. –

답변

1

첫 번째 문제는 비 제너릭 코드가 컴파일되지 않는다는 것입니다. 필드가 DataTypeB data;이고이 필드에 SparseArray<DataTypeB>을 할당합니다. 또한 setData은 전혀 컴파일되지 않습니다.

이 무시 ... 당신은 유형 매개 변수 A, B, C를 선언하고 인스턴스 필드 유형을 변경,하지만 당신은 여전히 ​​SparseArray<DataTypeB>B data에 시도하고 생성자에서 A myFragment-DataTypaA을 할당하고있다. 코드를 제네릭으로 마이그레이션 할 때 리팩토링과 같이 한 번에 한 단계 씩 접근해야합니다.

예를 들어 이제 다이빙으로 items = (C)myFragment.getData()을 살펴보십시오. fragment은 여전히 ​​DataTypaA 유형이므로 아마도 getData() 메서드는 제네릭 형식을 반환하지 않습니다. 뭔가 바뀌어야 할 것입니다.

당신은 할 일이 많으므로 자신을 반복하십시오 - 이것을 리팩토링 운동으로 간주하고 단계별로 진행하십시오.

  1. 비 제네릭 형식을 컴파일하십시오.
  2. myFragmentA myFragment으로 변경하고 유형 매개 변수 <A extends DataTypaA을 선언하십시오. 계속 진행하기 전에 이것을 컴파일하기 위해 수행해야 할 작업을 확인하십시오.
  3. 이제 dataSparseArray<B> data으로 이동하십시오. 아마도 이것은 SparseArray<T>이어야하며 TDataTypeB 또는 그 하위 유형입니다. 즉, B에 와일드 카드 기반 바인딩이 필요합니다. 비슷한 것 B extends SparseArray<? extends DataTypeB>
  4. 이제 items을 봅니다. 새 generic 형식 변수 A extends DataTypeA에서 반환되므로 DataTypeA은 generic이어야하고 getData에서 반환되는 제네릭 형식 변수가 있어야합니다. public T getData() { ... }으로 DataTypeA<T extends DataTypeC>으로 선언했다고 가정 해 보겠습니다.

당신의 유형 매개 변수 섹션에 변경 이제 :

class DataTypaA<T extends DataTypeC> 
... 
class myAdapter <A extends DataTypaA<C>, 
       B extends SparseArray<? extends DataTypeB>, 
       C extends DataTypeC> 
    extends FragmentStatePagerAdapter { 
    A myFragment; 
    SparseArray<B> data; 
    C items; 
... 

그것은이 당신이 게시 한 코드 부여와 너무 멀리 갈 어렵다 - 모든 클래스와 정보가, 그러나 이것은이다 과정을 따라야합니다.

예 : CDataTypeC으로 제한 할 필요가 없습니다. 그런 다음 유형 매개 변수 섹션을 myAdapterDataTypeA으로 변경합니다. SparseArray<B>에 대한 내 가정도 올바르지 않을 수 있습니다. 그러나 코드를 컴파일하지 못하여 말할 수 없습니다.

class DataTypaA<T extends DataTypeC> { 
    public T getData() { return null; } 
    public T getItems() { return null; } 
} 
class SparseArray<T, S> { 
    public T get(int foo) { return null; } 
    public void setTheData(S items){} 
} 
class DataTypeB { 
} 
class DataTypeC { 
    // do NOT use the raw type List - just done to get your code to compile 
    public List getList() { return null; } 
} 
abstract class FragmentStatePagerAdapter { 
    public abstract int getCount(); 
} 
class FragmentManager { 
} 
+0

답변 해 주셔서 감사합니다. 유형에 대한 구문 오류를 수정했습니다. 실제로 컴파일되지 않으며, 큰 아이디어를 위해 작성합니다. ''를 사용하지 마십시오. 비슷한 것을 가지고 있지 않은 타입에서도 작동하기 때문입니다. 내 문제는'public B getItem (int position) { return data.get (position);과 같이''유형을 반환해야하는 매개 변수를 초기화 할 때입니다. 재정의하는 동안 오류가 발생합니다. 이름을 변경하면 받아 들일 만하다. 또한'getCount()'에 문제가 있습니다 - 안드로이드 클래스에서 확장하므로 } –

+1

@AlexOpent를 제안한대로 추상으로 다시 작성할 수 없습니다. 'abstract' 사용은'getCount'에는 필요하지 않습니다 - 저는 안드로이드 라이브러리에서로드하는 대신 클래스를 위조해야했습니다. 'extends'는 선택 사항입니다 - 타입 매개 변수를 어떻게 사용해야하는지에 달려 있습니다. –

+1

@AlexOpent. 'public B getItem (int position) {return data.get (position);'에 대한 다른 질문에 대해서는 제네릭이 아닌 수퍼 유형 메서드를 재정의하는 것에 대한 새로운 질문을해야합니다. –

0

: DataTypaAA이되는 등

당신은 또한 당신이 다른 개체에 호출 방법에서 확인 반환 형식을 만들 필요가

(같은 fragment.getData())는 제네릭과 호환됩니다. 이를 위해 당신은 제네릭 형식이 알려진 클래스를 확장 나타낼 수 있습니다 :

public class MyAdapter<A extends MyData,B extends MyData,...> 

Java Tutorial on generics 자세한 내용은 좋은입니다.

관련 문제