6

我需要为我的班级配备多态克隆(深拷贝),即我需要这样的东西才能工作:

SuperType original = new SubType();
SuperType copy = original.clone();

whereoriginal.clone()可以被任何机制替代以创建深层副本,并且实际类型copy应为SubType,因为original也是SubType.

clone()方法和接口是Cloneable实现这一目标的唯一方法吗?工厂方法和复制构造函数不能被使用,因为实际的类只在运行时才知道,对吧?除了那些序列化反序列化方法以及恕我直言的Java深度克隆库比该方法更糟糕的黑魔法之外,还有其他建议的clone()方法吗?

谢谢,彼得

4

4 回答 4

4

实际上 Object 的clone()方法不允许你做任何多态调用,因为 is 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 对克隆与复制构造函数的看法

于 2013-04-03T14:45:13.843 回答
2

为了使您的代码工作,该代码要么在SuperType类或子类中,要么您的SuperType类型必须具有公共clone()方法。公共clone()方法不会自动存在,您必须实现它。就此而言,您可以将其称为其他任何名称,例如copy().

那么,您的问题是如何实现该clone()(或您所称的)方法,以便它进行多态克隆。

Java 开发人员的意图是调用super.clone(),假设继承层次结构中的所有类都类似地实现clone()以执行多态克隆。这最终得到了受保护的Object.clone()方法,它具有多态克隆的魔力。请注意,Object.clone()为了不引发异常,您的类必须实现Cloneable接口。

但是,还有其他可能的方式。例如,假设所有子类都有一个默认构造函数,您可以执行类似this.getClass().newInstance(). 这将创建正确类的对象,但不会复制字段。您的克隆方法将需要复制所有字段,子类必须覆盖您的克隆方法以复制其字段等。请注意,Cloneable在这种情况下是否实现接口无关紧要。

另一种方法是,假设类是可序列化的,序列化和反序列化this。这应该创建一个包含所有可序列化字段的多态克隆。

于 2013-04-03T23:20:22.983 回答
1

您可以简单地为 SuperType 添加一个复制方法并在所有 SubTypes 中实现它

class SuperType {

    public SuperType copy() {
              ...
    }
}
于 2013-04-03T14:38:10.557 回答
0

如果你不喜欢这个Cloneable界面,你可以创建自己的界面。每个类将负责创建正确类型的新实例。

于 2013-04-03T14:42:01.670 回答