尝试为此提出一个有意义的问题标题是棘手的。我会解释我到底要做什么。
我创建了一个Android图形库,可以构建一个可能很大的Path
个对象列表。我现在需要为每个Path
附加一些额外的数据。为此,我简单地将Path
(称为PathSubclass
)子类化,以提供额外的扩展数据字段。在一般用例中,只有极少数Path
个对象实际上会有额外的数据集。例如,可能有ArrayList
几千Path
秒,但只有少数人有额外的数据。在我开发库时,我希望附加到每个Path
的额外数据量可能会大幅增加。我很欣赏这可能是过早的优化,但是我担心,当很少填充额外的数据并且使用相当大的该对象集合时,将对象子类化为包含一些额外的数据是没有效率的。
我想做的可能是ExtendedPathData
类,与我的Path
子类分开。因此,每个Path
子类仅因需要mExtendedData
成员而略有膨胀,在许多情况下,null
成员将Path
,除了那些需要的View
个极少的对象附加数据。我认为这类似于通常使用setTag()
方法将其他数据附加到{{1}}的方式。
我还应该考虑其他任何方法,不管出于什么原因这样做会更好吗?
答案 0 :(得分:4)
您可以使用合成而不是继承。
创意1
PathData
类可能包含对Path
和ExtendedPathData
的引用:
// encapsulate properly in your code, this is
// just a short sample
class PathData {
public Path path;
public ExtendedPathData data;
}
这使您可以将data
成员设置为null
。每个PathData
实例的大小始终为两个引用。当ExtendedPathData
中的成员数增加时,实际内存消耗仅会增加到具有非空PathData
的{{1}}个实例。
创意2
您可以通过使用具有两个实现的接口来删除另一个引用:
data
由您自行决定是否确实有两个实现值得代码,因为您需要一个工厂方法来决定使用哪种实现。每个实例一个 4字节引用...
更多内容
如果interface PathData {
Path path();
ExtendedPathData data();
}
final class NullPathData implements PathData {
Path path;
public Path path() { return path; }
public ExtendedPathData data() { return null; }
}
final class ExtendedPathData implements PathData {
Path path;
ExtendedPathData data;
public Path path() { return path; }
public ExtendedPathData data() { return data; }
}
不可变且可能存在许多相等的实例,您也可以通过公开使用实例的静态工厂方法来池化它们pool 而不是公共构造函数。
如果你有Effective Java by Joshua Bloch,这里有更详细的解释提示(在更一般的背景下):
答案 1 :(得分:2)
不是整个继承点,可以在下面的容器中存储Path
的子类吗?
ArrayList<Path> pathList;
pathList.add(new Path());
pathList.add(new PathPlusPlus());
或者我不明白这个问题?
要消除丑陋的isinstanceof
调用,正如@assylias所建议的那样,你可以在你的基类中添加一个getter来返回扩展数据。在基类本身中它将返回null
,在子类中它将返回相关数据。