2012-10-26 30 views
9

我很困惑在我想克隆對象的類中重寫克隆方法。爲什麼要重寫Java中的克隆方法

對象類保護對象方法和按照所述受保護行爲,這是當一個方法被保護時,它只能由類本身訪問時,類的子類,或在同一個包中的類類

由於Java中的每個類都是從Object繼承而來的,所以它應該有clone方法,但我們仍然被迫重載clone。爲什麼需要?

此外,我已經在某些地方讀過重寫克隆對象並將其公開。我想知道,爲什麼這樣呢?

歡迎所有的答案。

+0

Ç關於克隆的razy詳細信息 - http://stackoverflow.com/questions/1138769/why-is-the-clone-method-protected-in-java-lang-object –

回答

8

由於Java中的每個類從對象擴展,所以它應該有克隆 方法但我們仍然不得不重寫克隆

不,你不會被強迫重寫clone方法。在繼承中,當你繼承一個類時,你不必強制重寫它的方法。它的修飾符被公開或保護並沒有太大區別。但是,如果您想直接在super類引用上調用方法,則該方法必須是public。受保護的方法只能通過繼承訪問。那就是你只能通過參考subclass來訪問它們。或者如果您覆蓋該方法,則可以通過super關鍵字訪問它們。

話雖如此,你不應該重寫clone方法,因爲它是broken。因爲,對於要克隆的類,您需要實現Cloneable界面。然後你的班級改爲使用Object類的clone方法。因爲,Cloneable接口並不完全具有任何方法cloning。代替使用Copy Constructor會是更好的選擇。

public class A { 
    private int data; 
    public A() { 
    } 

    public A(A a) { 
     this.data = a.data; 
    } 
} 

有關詳細信息,我建議要經過Joshua Bloch's有效的Java,它涵蓋使用clone方法的各個方面的這一章。

Effective Java- Item # 11 - Override clone judiciously

+0

正如你所寫的那樣:「不,你不必強制重寫克隆方法「,但如果克隆沒有被覆蓋,我不能直接在對象上調用克隆。爲什麼這樣? – Anand

+0

@anand。爲了調用任何'super class'方法,你需要一個該類的實例。現在,如果你重寫'clone'方法,那麼'Object'類的實例就是'super'。所以,你使用'super.clone()'來調用它。 –

+0

@anand。另外,你不能直接調用'Object'類的'clone'方法,因爲'clone'方法是'protected',並且只能通過'inheritance'在'base class'中訪問。所以,你可以通過同一個類的實例來調用它。但請注意,您需要處理'CloneNotSupportedException' –

4

我建議你閱讀約書亞布洛赫的Effective Java第2版。它有一個討論克隆的好章節。

我不會建議這樣做。我認爲這是一個JDK 1.0的錯誤。這本書會更清晰。

我建議你寫一個拷貝構造函數,而不是得到你想要的東西:

public class Foo { 
    private String name; 
    public Foo(String name) { this.name = name; } 
    public Foo(Foo f) { this.name = f.name; } // copy ctor here. 
} 
+0

複製構造函數不適用於繼承,這就是爲什麼我們有克隆 –

+1

不起作用?這是什麼樣子?我認爲克隆不會「繼承」繼承,除非鏈中的每個人都表現得非常謹慎。 Joshua Bloch在「Effective Java」中沒有提到關於Cloneable的好消息。 – duffymo

2

在許多情況下,目前還不清楚什麼是克隆的對象應該是它應該如何表現,所以如果你想你的類要克隆你必須明確地通過克隆克隆並公開它。

克隆可能沒有意義的情況包括代表某些資源的類,如網絡連接或同步鎖。如果這些對象可以克隆,克隆應該如何表現還不清楚。例如,網絡連接的克隆是否具有自己的TCP/IP連接,或者它以某種方式使用現有的連接?

0

克隆是Protected方法在Object類,所以它可以在課堂內使用。

關於access-當一個方法被保護時,它只能由類本身,類的子類或與類相同的包中的類訪問。

我看到一些誤解有關克隆方法

  1. clone()方法是protectedObject類,所以你不能叫clone()課外的。例如child.clone()如果不覆蓋,使接入public
  2. Cloneable是標記接口,如果你不標記Cloneable類,那麼你會得到CloneNotSupportedException如果調用clone()方法
  3. 如果一個類只包含基本字段或引用不可變對象,那麼通常情況下,super.clone返回的對象中沒有字段需要修改。
  4. 按照慣例,應通過調用super.clone獲取返回的對象。如果一個類和它的所有superclasses (except Object)服從這個約定,那將是這樣的情況,即x.clone().getClass() == x.getClass()

方法簽名低於

@Override 
public Object clone() throws CloneNotSupportedException { 
    return super.clone(); 
} 

參考文獻:

  1. Object#clone()
  2. Cloneable
-1
Why we do override clone() in cloning process? 
    //clone() in Object class is protected 
    package java.lang; 


    protected native Object clone() 
      throws CloneNotSupportedException; 

    java.lang is default import in our java applications. 

Note: If parent and sub class are both in same package then the methods in parent class are directly accessible. If they are in different package,then in subclass we have to override the parent class methods to use. 

    Note:Object class is in java.lang package,we are using it in different package,so we have to override the clone() which is protected in Object class 


first we will look into Protected method behavior.here is sample program to understand this 
    //this class is in com.anusha.clonetrial 
    package com.anusha.clonetrial; 

    public class A { 

     public A() 
     { 

     } 
     protected void disp1() 
     { 
      System.out.println("class a"); 
     } 
     protected void disp2() 
     { 
      System.out.println("class a"); 
     } 
    } 
    //below classes are in com.anusha.Test 
    package com.anusha.Test; 
    import com.anusha.clonetrial.A; 


    class AA { 


     protected void disp1() 
     { 
      System.out.println("class aa"); 
     } 

     protected void disp2() 
     { 
      System.out.println("class aa"); 
     } 
    } 

    //class B derived from AA which is present in the same package 
    class B extends AA 
    { 

     void show() 
     { 


      System.out.println("class b"); 
     } 
    } 

    //class C derived from A which is present in the different package 

    class C extends A 
    { 

     @Override 
     protected void disp1() 
     { 
      super.disp1(); 
     } 
     void show() 
     { 
      System.out.println("class c"); 
     } 
    } 

    package com.anusha.Test; 




    public class CloneTest { 


     public static void main(String[] args) { 
      B b=new B(); 
      C c=new C(); 
      b.disp1(); 
      b.disp2(); 
      c.disp1(); 
      c.disp2();//gives error because it is not overridden. 


     } 

    }