我需要装备我的类多态克隆(深拷贝),即我需要这样的工作:
SuperType original = new SubType();
SuperType copy = original.clone();
其中original.clone()
可以用任何机制替换来创建深度拷贝,而copy
的实际类型应为SubType
,因为original
也是SubType
。
clone()
方法和Cloneable
接口是实现这一目标的唯一途径吗?工厂方法和复制构造函数不能使用,因为只有在运行时才知道实际的类,对吗?除了那些序列化-反序列化方法和Java深度克隆库之外,还有其他建议的方法吗?在我看来,Java深度克隆库比clone()
方法更糟糕?
谢谢,切赫
实际上对象的clone()
方法不允许你做任何多态调用,因为是protected
。实现Cloneable
也没有用,因为它不包含clone()
方法。
可以通过为克隆类提供多态方法来进行多态克隆,而克隆类又调用复制构造函数。
abstract class SuperType {
public SuperType(SuperType t) {
}
public abstract SuperType deepCopy();
}
class SomeType extends SuperType {
SomeType(SomeType t) {
//copy constructor
}
@Override
public SomeType deepCopy() {
return new SomeType(this);
}
}
...
SuperType original = new SubType();
SuperType copy = original.deepCopy(); //the deepCopy is called on children classes
参见:
Joshua Block对克隆与复制构造器的看法
为了使您的代码工作,该代码要么在SuperType
类或子类内,要么您的SuperType
类型必须有一个公共clone()
方法。公共clone()
方法不会自动存在,您必须实现它。您可以将其命名为其他任何名称,例如copy()
。
你的问题,然后,是如何实现clone()
(或无论你叫它)的方法,使它做多态克隆。
Java开发人员想要的方法是调用super.clone()
,假设继承层次结构中的所有类都类似地实现clone()
来执行多态克隆。这最终到达受保护的Object.clone()
方法,该方法实现了多态克隆的魔力。注意,要使Object.clone()
不抛出异常,您的类必须实现Cloneable
接口。
然而,还有其他可能的方法。例如,假设所有子类都有一个默认构造函数,您可以执行类似this.getClass().newInstance()
的操作。这将创建正确类的对象,但不会复制字段。你的clone方法需要复制所有的字段,子类必须覆盖你的clone方法来复制它们的字段,等等。请注意,在这种情况下是否实现Cloneable
接口是无关的。
另一种方法是,假设该类是Serializable,序列化和反序列化this
。这将创建一个多态克隆,其中包含所有可序列化的字段。
您可以简单地为SuperType添加一个复制方法,并在所有subtype中实现它
class SuperType {
public SuperType copy() {
...
}
}
如果您不喜欢Cloneable
接口,您可以创建自己的接口。每个类将负责创建一个正确类型的新实例。