【发布时间】:2017-02-17 13:02:39
【问题描述】:
我不知道在从包裹中写入/读取时如何使用多态。 我知道我需要在基类以及所有派生类中实现 Parcelable(如果子类具有我想要写入包裹的其他属性)。 我不明白,我什至不知道它是否可能是 - 如何从 Parcelable 读取子类,即,我如何知道我正在从包裹中读取什么样的子类。 我可以做一些 hack,比如在 parcel 中写入一些指示符,告诉我要使用哪个类加载器,但我认为会有一些更优雅的方式,否则就没有太多使用多态性了。
为了说明我的问题,假设我有这样的课程:
形状类
public class Shape implements Parcelable {
public float area;
public Shape() {
}
public Shape(Parcel in) {
area = in.readFloat();
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeFloat(area);
}
//CREATOR etc..
}
RectangleShape.class
public class RectangleShape extends Shape {
float a;
float b;
public RectangleShape(Parcel in) {
super(in);
a = in.readFloat();
b = in.readFloat();
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeFloat(area);
dest.writeFloat(a);
dest.writeFloat(b);
}
//CREATOR etc..
}
CircleShape.class
public static class CircleShape extends Shape {
float r;
public CircleShape(Parcel in) {
super(in);
r = in.readFloat();
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeFloat(area);
dest.writeFloat(r);
}
//CREATOR etc..
}
现在,在其他课程中,我有这样的事情:
public class Geometry implements Parcelable {
Shape myShape;
public Geometry (boolean condition) {
if (condition)
myShape = new CircleShape(4.5);
else
myShape = new RectangleShape(3.4, 3.5);
}
@Override
public Geometry(Parcel in) {
in.readParcelable(??? - **how do I know what class loader to put here?** )
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(myShape,flags);
}
//CREATOR etc..
}
在没有隐式检查实例类型的情况下,我有什么方法可以在写入包裹时“告诉”android 它是什么子类?
【问题讨论】:
-
我遇到了类似的问题。在我的例子中,基类是一个接口,这让事情变得更容易。我想我解决它的方法是在接口中扩展
Parcelable(我们称之为Foo),然后我在其子类中实现了Foo,因此也实现了Parcelable。我不确定这是否有很大帮助...... -
我从来没有实现过 parcelable 扩展其他,但我想一个好的建议是检查谷歌自己是如何做到的。 AbsSavedState 是一个具有多个子类的 Parcelable 类。这是它的源代码android.googlesource.com/platform/frameworks/base/+/refs/heads/…,这里是 View.BaseSavedState android.googlesource.com/platform/frameworks/base/+/refs/heads/…
标签: java android polymorphism parcelable