可打包的抽象类

基本上,我的应用程序中有以下结构:

uml of my app

在没有抽象类的情况下实现这样的结构是很简单的,但是在这种情况下,我不知道如何实现它。ProjectItem

抽象类需要一个,因为它应该是可打包的。(如在构造函数项目(宗地)中)ProjectItemCREATORin.readTypedList(mProjectItems, ProjectItem.CREATOR);

但实际上,由于逻辑原因,只能在其派生类中实现 。CREATOR

那么,如何实现这种结构以保持类的可包裹性?Project

编辑

这是 的构造函数之一的样子:Project

private Project(Parcel in) {
    in.readTypedList(mProjectItems, ProjectItem.CREATOR);
}

但正如我已经说过的,不应该必须实现ProjectItemCREATOR


答案 1

我的解决方案类似于evertvandenbruel的解决方案。但是我使用int标识具体类,以便我可以使用开关块。我在静态getConcreteClass(Parcel)方法中也有那个开关块。

抽象类.java

public abstract class AbstractClass implements Parcelable {

public static final int CLASS_TYPE_ONE = 1;
public static final int CLASS_TYPE_TWO = 2;

public static final Creator<AbstractClass> CREATOR = new Creator<AbstractClass>() {
    @Override
    public AbstractClass createFromParcel(Parcel source) {

        return AbstractClass.getConcreteClass(source);
    }

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

protected String mAbstractClassString;

public AbstractClass(String abstractClassString) {
    mAbstractClassString = abstractClassString;
}

public AbstractClass(Parcel source) {
    mAbstractClassString = source.readString();
}

public static AbstractClass getConcreteClass(Parcel source) {

    switch (source.readInt()) {
        case CLASS_TYPE_ONE:
            return new ConcreteClassOne(source);
        case CLASS_TYPE_TWO:
            return new ConcreteClassTwo(source);
        default:
            return null;
    }
}

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

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(mAbstractClassString);
}

@Override
public String toString() {
    return "Parent String: " + mAbstractClassString + '\n';
}
}

混凝土类一.java

public class ConcreteClassOne extends AbstractClass {

private String mString;

public ConcreteClassOne(String abstractClassMemberString, String string) {
    super(abstractClassMemberString);

    mString = string;
}

public ConcreteClassOne(Parcel source) {
    super(source);
    mString = source.readString();
}

@Override
public void writeToParcel(Parcel dest, int flags) {

    dest.writeInt(CLASS_TYPE_ONE);
    super.writeToParcel(dest, flags);
    dest.writeString(mString);
}

@Override
public String toString() {
    return super.toString().concat("Child String: " + mString);
}
}

混凝土类二.java

public class ConcreteClassTwo extends AbstractClass {

private String mString;
private int mInt;

public ConcreteClassTwo(String abstractClassString, String string, int anInt) {
    super(abstractClassString);
    mString = string;
    mInt = anInt;
}

public ConcreteClassTwo(Parcel source) {
    super(source);
    mString = source.readString();
    mInt = source.readInt();
}

@Override
public void writeToParcel(Parcel dest, int flags) {

    dest.writeInt(CLASS_TYPE_TWO);
    super.writeToParcel(dest, flags);
    dest.writeString(mString);
    dest.writeInt(mInt);
}

@Override
public String toString() {

    String string = super.toString();
    for (int i = 0; i < mInt; i++) {
        string = string.concat("Child String: " + mString + '\n');
    }
    return string;
}
}

答案 2

选择的答案(来自evertvandenbruel的帖子)中有一个错误。当只对一个子类进行打包时,正确的代码必须考虑打包,而不仅仅是超类对象的列表。

所有其他代码应该是相同的,关键是您必须在所有创建者中读取类型变量(请参阅下面的代码)。否则,在尝试取消拆分子类对象时,排序将出现问题

前任:

package com.example.parcelable_example.model;

import android.os.Parcel;
import android.os.Parcelable;

public class Cat extends Animal{

    public Cat(String name){
        super(name, "Cat");
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(getType());
        super.writeToParcel(dest, flags);
    }

    public Cat(Parcel source) {
        super(source);      
    }

    public static final Parcelable.Creator<Cat> CREATOR = new Parcelable.Creator<Cat>() {
        public Cat createFromParcel(Parcel in) {
            /** DO NOT FORGET THIS!!! **/
            type = in.readString();
            return new Cat(in);
        }

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

}

推荐