我需要为我的班级配备多态克隆(深层复制),即我需要这样的工作:
SuperType original = new SubType();
SuperType copy = original.clone();
其中original.clone()
可以替换为任何创建深层副本的机制,copy
的实际类型应为SubType
,因为original
也是SubType
1}}。
clone()
方法和Cloneable
接口是实现此目的的唯一方法吗?工厂方法和复制构造函数不能使用,因为实际的类只在运行时才知道,对吗?除了那些序列化 - 反序列化方法之外还有其他任何建议的方法吗?Java deep-cloning library这是恕我直言,甚至比clone()
方法更糟的黑魔法?
谢谢,彼得
答案 0 :(得分:4)
实际上,对象的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
另见:
答案 1 :(得分:2)
为了让您的代码正常工作,该代码位于SuperType
类或子类中,或者您的SuperType
类型必须具有公共clone()
方法。公共clone()
方法不会自动存在,您必须实现它。你可以把它称之为其他任何事情,例如copy()
。
然后,您的问题是如何实现clone()
(或任何您称之为)的方法,以便进行多态克隆。
Java开发人员打算采用的方式是调用super.clone()
,假设继承层次结构中的所有类都类似地实现了clone()
来执行多态克隆。这最终会进入受保护的Object.clone()
方法,它可以实现多态克隆的神奇功能。请注意,要使Object.clone()
不抛出异常,您的类必须实现Cloneable
接口。
然而,还有其他可能的方法。例如,假设所有子类都有默认构造函数,您可以执行this.getClass().newInstance()
之类的操作。这将创建正确类的对象,但不会复制字段。您的克隆方法需要复制所有字段,子类必须覆盖您的克隆方法以复制其字段等。请注意,在这种情况下是否实现Cloneable
接口无关紧要。
另一种方法是,假设该类是Serializable,以序列化和反序列化this
。这应该创建一个多态克隆,其中包含所有可序列化的字段。
答案 2 :(得分:1)
您可以简单地将复制方法添加到SuperType并在所有子类型中实现
class SuperType {
public SuperType copy() {
...
}
}
答案 3 :(得分:0)
如果您不喜欢Cloneable
界面,则可以创建自己的界面。每个类都将负责创建正确类型的新实例。