2015-02-17 16 views
8

Mam abstrakcyjną klasę A, która implementuje Parcelable.Dziedziczenie spadkowe: klasa abstrakcyjna - Który STWÓRCA?

Mam klasę B i klasę C, które obaj rozszerzają A. Jak mogę je rozdzielić?

Z tego powodu mogłem połączyć go i dostarczyć CREATOR zarówno w A jak i B, jak sugerowano w wielu postach. Ale ponieważ mam inne obiekty, które przechowywać A-B-C klas i wdrożenia Parcelable themselfes, że takie podejście nie wydaje się działać, bo gdy chcę przejść ArrayList A musiałbym użyć CREATOR w wpisywanych listy przez

ArrayList<A> elements = new ArrayList<>(); 
in.readTypedList(elements , B.CREATOR); // B.CREATOR? C.CREATOR??? 

Co oczywiście nie ma sensu. Jak więc właściwie zrobić A Parcelable?

Ja chcę sprawić, że ta klasa będzie działała w trybie paczkowym, aby móc odnieść się do litery A w zwykły sposób.

)

public abstract class A implements Parcelable { 

    final String globalVar; 

    public A(String globalVar) { 
     this.globalVar = globalVar; 
    } 
} 

B)

public class B extends A { 

    String bVar; 


    public B(String global, String bVar) { 
     super(global); 
     this.bVar = bVar; 
    } 

    private B(Parcel in) { 
     super(in.readString()); 
     this.bVar = in.readString(); 
    } 


    @Override 
    public int describeContents() { 
     return 0; 
    } 

    @Override 
    public void writeToParcel(Parcel parcel, int i) { 
     parcel.writeString(bVar); 
    } 
} 

C)

public class C extends A { 

    String cVar; 


    public C(String global, String cVar) { 
     super(global); 
     this.cVar = cVar; 
    } 

    @Override 
    public int describeContents() { 
     return 0; 
    } 

    @Override 
    public void writeToParcel(Parcel parcel, int i) { 
     parcel.writeString(cVar); 
    } 
} 
+0

która jest abstrakcyjna – Blackbelt

+0

A. Edytowana odpowiedź. –

+0

, ale nie możesz mieć twórcy w A, ponieważ nie można utworzyć instancji, byłoby łatwiej, gdybyś opublikował przynajmniej część A – Blackbelt

Odpowiedz

-2
public class A implements Parcelable{ 

     public A(){ 

     } 

     public A(Parcel in){ 
      super(in); 
      // read from parcel 
      // number = in.readInt() etc 
     } 

     @Оverride 
     public int describeContents(){ 
      return 0; 
     } 

     @Override 
     public void writeToParcel(Parcel dest, int flags) { 
      super.writeToParcel(out, flags); 
      // write to parcel 
      // out.writeInt 
     } 
     public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 
      public Student createFromParcel(Parcel in) { 
       return new A(in); 
      } 

      public A[] newArray(int size) { 
       return new A[size]; 
      } 
     }; 
    } 

B i C należy również wdrożyć Parcelable

+0

A jak dane z B i C napisane wtedy? To byłby martwy Parszywek nic nie robiący, czy coś mi brakuje? –

+0

'super.writeToParcel (obecnie, flagi)'; i 'super (in)' w B i C sprawi, że dane z A zostaną odczytane. B i C również muszą implementować Parcelable – user840754

+0

Ale w części problematycznej, gdy nie znamy typu. Jak mogę to zrobić? Jeśli wezwę STWÓRCĘ twojej klasy, B i C nie zostaną dotknięte, prawda? –

11

użyłem parcelable architekturę Vincenta mimoun-Prat jest z tego postu: Parcelable and inheritance in Android i wpadł na tej samej liście wpisany problemu o konieczności określenia niemożliwy abstrakcyjne twórcy.

wyszukiwania w JavaDoc DROBNICOWEJ jest, że okazało się, że sposób writeList(List val) wewnętrznie używa writeValue(Object) sposób dla każdego obiektu na liście, a tym samym wywołanie writeToParcel() z podklasy (B i C z liście). Aby odrzucić listę, użyj jej odpowiednika readList (List outVal, ClassLoader loader), gdzie A ClassLoader musi zostać przekazany lub przynajmniej w moim przypadku zostanie wysłane android.os.BadParcelableException.

Klasa zawierający listę elementów powinno być coś takiego:

public class AContainer implements Parcelable { 
    //Other AContainer fields 
    List<A> elements = new ArrayList<>(); 
    //Other AContainer fields 

    static final Parcelable.Creator<AContainer> CREATOR = new Parcelable.Creator<AContainer>() { 
     @Override 
     public AContainer createFromParcel(Parcel source) { 
      return new AContainer(source); 
     } 

     @Override 
     public AContainer[] newArray(int size) { 
      return new AContainer[size]; 
     } 
    }; 

    public AContainer() { 
    } 

    protected AContainer(Parcel source) { 
     //read other AContainer fields 
     source.readList(elements, A.class.getClassLoader()); 
     //read other AContainer fields 
    } 

    @Override 
    public int describeContents() { 
     return 0; 
    } 

    @Override 
    public void writeToParcel(Parcel dest, int flags) { 
     //write other AContainer fields 
     dest.writeList(elements); 
     //write other AContainer fields 
    } 
} 

Stosując te metody mogą być nieco wolniejszy niż readTypedList() i writeTypedList() jednak konkretnych danych z B i C podklasy jest również „zapakowane” i nie tylko pola z abstrakcyjnej superklasy (niemożliwe będzie abstrakcyjne). Odzyskujesz właściwe instancje z B i C.

+0

Ratująca życie odpowiedź. Po pierwsze nie mogłem znaleźć przyczyny awarii podczas usuwania aplikacji, wtedy nie wiedziałem, jak to naprawić. Na szczęście twój post sprawił, że moja dwugodzinna depresja skończyła się z uśmiechem. Dzięki! – Sufian

+0

Należy zauważyć, że 'element' musi zostać zainicjowany przed wywołaniem metody' Parcel.readList() '. – Henry