2012-10-26 9 views
9

Jestem zdezorientowany odnośnie do przesłonięcia metody klonowania w klasie, dla której chcę sklonowanego obiektu.Dlaczego zastąpić metodę klonowania w Javie

klasa obiektu jest chroniony obiekt metody, jak na chronionym zachowanie, które jest Gdy sposób jest chroniona, może być dostępny tylko dla samej klasy, podklasy grupy lub klasy w tym samym opakowaniu Jako klasa.

Jak każda klasa w Javie rozciąga się od Object, więc powinna mieć metodę klonowania, ale wciąż jesteśmy zmuszeni do przesłonięcia klona. Dlaczego jest wymagany?

Ponadto, czytałem w niektórych miejscach, aby zastąpić obiekt klonu i upublicznić go. Zastanawiam się, dlaczego tak jest?

Wszystkie odpowiedzi są mile widziane.

+0

C więcej szczegółów na temat klonu - http://stackoverflow.com/questions/1138769/why-is-the-clone-method-protected-in-java-lang-object –

Odpowiedz

8

Ponieważ każda klasa w Javie rozciąga się od obiektu, więc powinien mieć klon metody, ale nadal jesteśmy zmuszeni zastąpić klon

Nie, nie są zmuszeni zastąpić metodę clone. W dziedziczeniu, gdy dziedziczysz klasę, nie jesteś zmuszony do przesłonięcia tej metody. Modyfikator, który jest publiczny lub chroniony, nie ma większego znaczenia. Jeśli jednak chcesz wywołać metodę bezpośrednio na odwołaniu klasy super, ta metoda musi być public. Chronione metody są dostępne tylko poprzez dziedziczenie. To znaczy, że możesz uzyskać do nich dostęp tylko przez odniesienie subclass. Lub jeśli zastąpisz tę metodę, możesz uzyskać do niej dostęp za pomocą słowa kluczowego super.

Po tym, nie należy przesłonić metody clone, ponieważ jest to broken. Ponieważ, aby klasa była klonowana, musisz zaimplementować interfejs Cloneable. A następnie twoja klasa korzysta z klasy clone z klasy Object. Ponieważ interfejs Cloneable nie ma dokładnie żadnej metody dla cloning. Byłoby lepszym rozwiązaniem użycie zamiast tego Copy Constructor.

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

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

Aby uzyskać więcej szczegółów, chciałbym zaproponować, aby przejść przez ten rozdział Joshua Bloch's Effective Java, który obejmuje wszystkie aspekty korzystania clone metody.

Effective Java- Item # 11 - Override clone judiciously

+0

Jak pisałeś: "Nie, nie jesteś zmuszony do zignorowania Metoda klonowania "ale nie mogę wywołać klonu bezpośrednio na obiekcie, jeśli klon nie zostanie nadpisany. Dlaczego tak jest? – Anand

+0

@anand. Aby wywołać dowolną metodę "superklasy", potrzebujesz instancji tej klasy. Teraz, jeśli nadpisujesz metodę 'clone', masz instancję klasy' Object' jako 'super'. Używasz 'super.clone()', aby go wywołać. –

+0

@anand. Ponadto, nie można bezpośrednio wywołać metody 'clone' na instancji klasy Object, ponieważ metoda' clone' jest 'protected' i jest dostępna tylko w' klasie bazowej' przez 'dziedziczenie'. Możesz go wywołać przez instancję tej samej klasy. Ale pamiętaj, musisz obsłużyć 'CloneNotSupportedException' –

4

polecam czytanie Joshua Bloch za Effective Java 2nd edition. Ma dobry rozdział omawiający klon.

Nie radziłbym robić tego. Uważam to za błąd JDK 1.0. Książka uczyni to jaśniejszym.

Polecam pisanie konstruktor kopiujący zamiast dostać to, co chcesz:

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

Konstruktor kopiowania nie działa z dziedziczeniem, dlatego mamy klon –

+1

Nie działa? Jak to wygląda? Twierdzę, że klon nie "działa" również z dziedziczeniem, chyba że wszyscy w łańcuchu wykazują wielką ostrożność. Joshua Bloch nie mówi dobrych rzeczy o Klonowalnym w "Efektywnej Javie". – duffymo

2

W wielu przypadkach nie jest jasne, co klonować obiekt powinien być i jak powinno się zachowywać, więc jeśli chcesz swoją klasę aby być klonowalnym, musisz powiedzieć to wprost przez przemilczenie klona i upublicznienie go.

Przypadki, w których klon może nie mieć sensu, obejmują klasy reprezentujące pewne zasoby, takie jak połączenie sieciowe lub blokada synchronizacji.Jeśli te obiekty można sklonować, nie jest jasne, jak zachowywać się klon. Na przykład, czy klon połączenia sieciowego ma własne połączenie TCP/IP, czy też w jakiś sposób korzysta z istniejącego?

0

Klon jest metodą Protected w klasie Object, więc jest dostępna dla ciebie w klasie.

Informacje o dostępie - gdy metoda jest chroniona, dostęp do niej może mieć sama klasa, podklasy klasy lub klasy w tym samym pakiecie co klasa.

widzę pewne błędne przekonania na temat metody clone

  1. clone() metoda jest protected wewnątrz Object klasy, więc nie można nazwać clone() poza klasą. na przykład child.clone() chyba zastąpić je i uczynić dostęp public
  2. Cloneable jest interfejs marker i jeśli nie oznaczyć klasę Cloneable wtedy dostaniesz CloneNotSupportedException jeśli zadzwonisz clone() metoda
  3. Jeśli klasa zawiera tylko prymitywne pola lub odniesień do niezmiennych obiektów, wtedy zwykle trzeba zmodyfikować żadne pola obiektu zwrócone przez super.clone.
  4. Zgodnie z konwencją zwracany obiekt należy uzyskać, dzwoniąc pod numer super.clone. Jeśli klasa i wszystkie jej znaki superclasses (except Object) są zgodne z tą konwencją, stanie się tak w przypadku, gdy x.clone().getClass() == x.getClass().

podpis Sposób jest poniżej

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

Literatura:

  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. 


     } 

    } 
Powiązane problemy