2012-10-26 2 views
9

में क्लोन विधि को ओवरराइड क्यों करें मैं कक्षा में क्लोन विधि को ओवरराइड करने के बारे में उलझन में हूं जिसके लिए मुझे क्लोन ऑब्जेक्ट चाहिए।जावा

वस्तु वर्ग वस्तु की रक्षा की है विधि और संरक्षित व्यवहार जो है जब एक विधि सुरक्षित है, यह केवल वर्ग अपने आप में पहुँचा जा सकता है के अनुसार, के रूप में एक ही पैकेज में वर्ग के उपवर्गों, या वर्गों कक्षा

चूंकि जावा में प्रत्येक वर्ग ऑब्जेक्ट से फैली हुई है, इसलिए इसमें क्लोन विधि होनी चाहिए लेकिन फिर भी हमें क्लोन को ओवरराइड करने के लिए मजबूर होना पड़ता है। इसकी आवश्यकता क्यों है?

इसके अलावा, मैंने क्लोन ऑब्जेक्ट को ओवरराइड करने और इसे सार्वजनिक करने के लिए कुछ स्थानों पर पढ़ा है। मुझे आश्चर्य है, ऐसा क्यों है?

सभी उत्तरों का स्वागत है।

+0

सी क्लोन पर रेजी विवरण - http://stackoverflow.com/questions/1138769/why-is-the-clone-method-protected-in-java-lang-object –

उत्तर

8

जावा में हर वर्ग वस्तु तक फैली हुई है, तो यह क्लोन विधि होनी चाहिए, लेकिन अभी भी हम क्लोन ओवरराइड करने के लिए

आप कोई clone विधि ओवरराइड करने के लिए मजबूर नहीं कर रहे हैं मजबूर कर रहे हैं। विरासत में, जब आप कक्षा प्राप्त करते हैं, तो आपको इसकी विधि को ओवरराइड करने के लिए मजबूर नहीं किया जाता है। इसका संशोधक सार्वजनिक या संरक्षित होने से कोई फर्क नहीं पड़ता है। हालांकि, अगर आप super कक्षा संदर्भ पर सीधे एक विधि का आह्वान करना चाहते हैं, तो उस विधि को public होना चाहिए। संरक्षित तरीके केवल विरासत के माध्यम से सुलभ हैं। यही है कि आप उन्हें केवल subclass संदर्भ के माध्यम से एक्सेस कर सकते हैं। या यदि आप विधि को ओवरराइड करते हैं, तो आप उन्हें super कीवर्ड के माध्यम से एक्सेस कर सकते हैं।

ऐसा कहकर, आपको clone विधि ओवरराइड नहीं करना चाहिए, क्योंकि यह broken है। क्योंकि, कक्षा को क्लोन करने के लिए, आपको Cloneable इंटरफ़ेस को लागू करने की आवश्यकता है। और फिर आपकी कक्षा विधि Object कक्षा का उपयोग करती है। क्योंकि, Cloneable इंटरफ़ेस में cloning के लिए बिल्कुल कोई विधि नहीं है। इसके बजाय Copy Constructor का उपयोग करने का एक बेहतर विकल्प होगा।

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

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

अधिक जानकारी के लिए, मैं Joshua Bloch's प्रभावी जावा, जो clone विधि का उपयोग कर के सभी पहलुओं को शामिल किया गया के इस अध्याय के माध्यम से जाना सुझाव है।

Effective Java- Item # 11 - Override clone judiciously

+0

जैसा कि आपने लिखा था "नहीं, आपको ओवरराइड करने के लिए मजबूर नहीं किया गया है क्लोन विधि "लेकिन अगर क्लोन ओवरराइड नहीं किया गया है तो मैं सीधे ऑब्जेक्ट पर क्लोन को कॉल नहीं कर सकता। ऐसा क्यों है? – Anand

+0

@anand। 'सुपर क्लास' की किसी भी विधि का आह्वान करने के लिए आपको उस वर्ग का एक उदाहरण चाहिए। अब, यदि आप 'क्लोन' विधि को ओवरराइड करते हैं, तो आपके पास 'ऑब्जेक्ट' वर्ग का वह उदाहरण 'सुपर'' है। तो, आप इसे आमंत्रित करने के लिए 'super.clone()' का उपयोग करते हैं। –

+0

@anand। साथ ही, आप 'ऑब्जेक्ट' वर्ग के उदाहरण पर सीधे 'क्लोन' विधि को कॉल नहीं कर सकते हैं, क्योंकि 'क्लोन' विधि 'संरक्षित' है, और केवल 'विरासत' के माध्यम से 'बेस क्लास' में पहुंच योग्य है। तो, आप इसे उसी कक्षा के उदाहरण के माध्यम से आमंत्रित कर सकते हैं। लेकिन सावधान रहें, आपको उपरोक्त बिंदु पर 'क्लोन नॉटस्पेटेडएक्सप्शन' –

4

मैं यहोशू बलोच के Effective Java 2 संस्करण पढ़ने की सलाह देते हैं। क्लोन पर चर्चा करने के लिए इसका एक अच्छा अध्याय है।

मैं ऐसा करने की सलाह नहीं दूंगा। मैं इसे एक जेडीके 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

काम नहीं करता है? वह किस तरह का दिखता है? मैं तर्क दूंगा कि क्लोन विरासत के साथ "काम" नहीं करता है, जब तक कि श्रृंखला में हर कोई बहुत अच्छी देखभाल नहीं करता है। जोशुआ ब्लोच "प्रभावी जावा" में क्लोनेबल के बारे में अच्छी बातें नहीं कहता है। – duffymo

2

कई मामलों में यह स्पष्ट नहीं है कि क्या एक क्लोन वस्तु होना चाहिए और यह कैसे व्यवहार करना चाहिए, इसलिए यदि आप अपने वर्ग हैं:

मैं बजाय एक प्रति निर्माता लिख ​​आप क्या चाहते हैं पाने के लिए सलाह देते हैं क्लोनबल होने के लिए आपको क्लोन को ओवरराइड करके और इसे सार्वजनिक करके स्पष्ट रूप से कहना होगा।

मामले जहां क्लोन समझ में नहीं आता है वे वर्ग शामिल हैं जो नेटवर्क संसाधन या सिंक्रनाइज़ेशन लॉक जैसे कुछ संसाधनों का प्रतिनिधित्व करते हैं।अगर इन वस्तुओं को क्लोन किया जा सकता है तो यह स्पष्ट नहीं है कि क्लोन का व्यवहार कैसे किया जाना चाहिए। उदाहरण के लिए, क्या नेटवर्क कनेक्शन के क्लोन में स्वयं का एक टीसीपी/आईपी कनेक्शन होता है या क्या यह किसी मौजूदा तरीके से उपयोग करता है?

0

क्लोन ProtectedObject कक्षा में विधि है, इसलिए यह कक्षा के अंदर आपके लिए सुलभ है।

पहुंच के बारे में- जब कोई विधि सुरक्षित होती है, तो इसे कक्षा के समान पैकेज में कक्षा के स्वयं के वर्ग, वर्ग के वर्गों या वर्गों द्वारा ही एक्सेस किया जा सकता है।

मैं क्लोन विधि के बारे में कुछ गलतफहमी देखने

  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. 


     } 

    }