2010-09-06 69 views
0

这样做可以调用Asub的克隆方法吗?或者Asub深度克隆正确?如果没有,有没有办法通过这种方法来推动深度克隆阿斯布?在Java中克隆对象[3个问题]

abstract class Top extends TopMost { 
    protected Object clone() { 
     Object obj = super.clone(); 
     // deep copy and try catch 
    } 


} 

abstract class A extends Top { 
    protected Object clone() { 
     Object obj = super.clone(); 
     // deep copy and try catch 
    } 


} 

class Asub extends A { 
    protected Object clone() { 
     Object obj = super.clone(); 
     // deep copy and try catch 
    } 

    public void doSomethingNew() { 
    } 
} 

abstract class TopMost { 
    public void someMethod() { 
     Top a = (Top) super.clone(); 
     // more code here 
    } 
} 

public class Main { 
    public static void main(String... args) { 
     Asub class1 = new Asub(); 
     class1.someMethod(); 
    } 
} 

回答

1

允许所有abstract子类实现super.clone()基本上什么也不做(因为你所有的抽象类的例子什么都不做),并调用(在结束)Object.clone()方法。

我的建议是允许所有的具体类(如ASUP)覆盖克隆方法和使用copy constructor成语创建的本身精确克隆....

例如

public abstract class TopMost { 

    public TopMost(TopMost rhs) { 

    } 

} 

public abstract class Top extends TopMost { 

    public Top(Top rhs) { 
     super(rhs); 

     //whatever you need from rhs that only is visible from top 
    } 
} 

public abstract class A extends Top { 

    public A (A rhs) { 
     super(rhs); 

     //TODO: do rhs copy 
    } 
} 

public class ASub extends A { 

    public ASub(ASub rhs) { 
     super(rhs); 

     //TODO: copy other stuff here.... 
    } 

    public Object clone() { 
     return new ASub(this); 
    } 
} 

PSTopMostCloneable的

+0

不幸的是,如果'ASub'进一步子类化,子类'clone()'可能不会调用'super.clone()',因为它返回一个'ASub',而不是一个'ASubSub'。所以这只有在完全控制整个类层次结构时才有效(并仔细记录了他/她的后继者的不合格克隆实现)。 – 2010-09-06 16:28:29

+0

@PéterTörök,我完全同意你的意见。 – 2010-09-06 16:51:18

+0

感谢您的回复家伙 – Joset 2010-09-06 17:01:46

3

首先,注意the clone() interface is broken,因此不应该在新的代码中使用。 实施拷贝构造函数代替更好。

但是,如果您真的需要这样做,正确的方法是为TopMost实施Cloneable。为什么?说有效的Java第2版,项目11:

那么Cloneable做什么,因为它不包含任何方法?它决定了 Object的保护行为clone执行:如果一个类实现 Cloneable,Object的克隆方法返回该对象的一个​​字段的字段副本; 否则会抛出CloneNotSupportedException。这是一个非常非典型的使用 的接口,而不是一个被模拟。通常情况下,实现一个接口 说什么类可以为客户做。在Cloneable, 的情况下,它修改了超类上受保护方法的行为。

此外,Asub.clone应该声明public,不protected - 否则你无法从外界调用它。另外,如果您使用的是Java5或更高版本,那么Asub.clone返回Asub而不是Object(以及类似的超类)是合法和可取的。

您不会在类中显示任何成员 - 各种类中clone的实现可能会有很大的不同,具体取决于该类中成员的类型。也就是说,如果一个类有任何可变成员,你需要仔细深入复制所有这些成员,否则你最终会得到不同的对象共享它们的内部状态。

但是,假设你的类只有原始的或不可变的领域,克隆作品如预期,虽然你有很多不必要的clone方法在抽象类,所有这些都只需拨打super.clone() - 你可能会与Asub.clone()更好只要。作为一个方面说明,如果Top a = (Top) super.clone()不是一个错字,你引入了从基类到派生类的依赖关系,这不是一个好主意。

+1

是和'maybe'不是因为'Cloneable'只是一个标记接口。 – 2010-09-06 16:00:10

+0

@精英绅士,不幸的是,Cloneable不仅仅是一个标记界面。查看我的更新。 – 2010-09-06 16:08:37

+0

@PéterTörök,总而言之,Asub被深度克隆,所有领域,包括来自抽象类的领域都被赋予了新的参考和副本。 – Joset 2010-09-06 16:14:03

0

super.clone()呼叫禁用虚拟机制,所以它仅调用Object.clone()

+0

抱歉删除了其他someMethod它应该只在TopMost – Joset 2010-09-06 16:01:56