2010-09-06 71 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