2012-11-15 17 views
5

मुझे अचानक जावा में गहरी पॉलिमॉर्फिक प्रति बनाने की समस्या का सामना करना पड़ा है। कार्यान्वयन क्लोनबल मेरे मामले में समस्या हल करता है, लेकिन इसे अक्सर "खराब" तकनीक के रूप में जाना जाता है।जावा में पॉलिमॉर्फिक प्रति

public class Parent { 
    int x; 

    public Parent() {} 

    public Parent(int x0) { 
     x = x0; 
    } 

    public Parent copy() { 
     Parent b = new Parent(); 
     b.assign(this); 

     return b; 
    } 

    protected void assign(Parent c) { 
     x = c.x; 
    } 

    @Override 
    public String toString() { 
     return getClass().getName() + ", " + x; 
    } 
} 

public class Child extends Parent { 
    int y; 

    protected Child() {} 

    public Child(int x0, int y0) { 
     super(x0); 
     y = y0; 
    } 

    @Override 
    public Child copy() { 
     Child b = new Child(); 
     b.assign(this); 

     return b; 
    } 

    @Override 
    protected void assign(Child c) { 
     super.assign(c); 
     y = c.y; 
    } 

    @Override 
    public String toString() { 
     return getClass().getName() + ", " + x + "," + y; 
    } 
} 

public class Test { 
    public static void main(String[] args) { 
     Parent x = new Parent(5); 
     Child y = new Child(10, 20); 
     Parent z = x.copy(); 
     Parent w = y.copy(); 

     System.out.println(x); 
     System.out.println(y); 
     System.out.println(z); 
     System.out.println(w); 
    } 
} 

उत्पादन होता है:

com.xxx.zzz.Parent, 5 
com.xxx.zzz.Child, 10,20 
com.xxx.zzz.Parent, 5 
com.xxx.zzz.Child, 10,20 

और एक और (कम) एक ही ऐसा करने का तरीका (का उपयोग कर

तो, यहाँ एक "नहीं-Clonable" समाधान खोजने के लिए मेरे प्रयास कर रहे हैं प्रतिबिंब):

public class Parent { 
    int x; 

    public Parent() {} 

    public Parent(int x0) { 
     x = x0; 
    } 

    public Parent copy() { 
     try { 
      Parent b = getClass().newInstance(); 
      b.assign(this); 
      return b; 
     } catch (InstantiationException | IllegalAccessException e) { 
      e.printStackTrace(); 
      return null; 
     } 
    } 

    protected void assign(Parent c) { 
     x = c.x; 
    } 

    @Override 
    public String toString() { 
     return getClass().getName() + ", " + x; 
    } 
} 

public class Child extends Parent { 
    int y; 

    protected Child() {} 

    public Child(int x0, int y0) { 
     super(x0); 
     y = y0; 
    } 

    protected void assign(Child c) { 
     super.assign(c); 
     y = c.y; 
    } 

    @Override 
    public String toString() { 
     return getClass().getName() + ", " + x + "," + y; 
    } 
} 

बाल वर्ग में प्रतिलिपि प्रतिलिपि() की आवश्यकता नहीं है। लेकिन मुझे यकीन नहीं है कि getClass() का उपयोग करना कितना 'कानूनी' है। एक प्रति प्लेसहोल्डर बनाने के लिए नयाInstance() ...

क्या उपयोग करने के लायक समाधान या अधिक सामान्य/मजबूत/सरल दृष्टिकोण हैं?

धन्यवाद!

+0

यदि बच्चे के पास डिफॉल्ट कन्स्ट्रक्टर है तो यह काम नहीं करता है। –

उत्तर

0

एक कॉपी कन्स्ट्रक्टर या क्लोनेबल का उपयोग करने के विकल्प के रूप में आप अपनी प्रतिलिपि करने के लिए क्रमबद्धता का उपयोग कर सकते हैं।

http://www.javaworld.com/javaworld/javatips/jw-javatip76.html?page=2

2

आपका समाधान, मेरे लिए ठीक लग रहा है इस विशेष उपयोग के मामले के लिए।

newInstance() का उपयोग करने का मुख्य सीमाओं, कर रहे हैं:

  • यह केवल वस्तुओं जो नहीं-आर्ग निर्माता के साथ काम करता है, और
  • यह वस्तुओं जो अंतिम क्षेत्रों
  • है क्लोन करने में असमर्थ होगा

कुछ पुस्तकालय हैं जो क्लोनिंग का समर्थन करते हैं। Kryo पर एक नज़र डालें। यह एक सीरियलाइजेशन लाइब्रेरी है जो क्लोनिंग (गहरी और उथली) का समर्थन करती है, जिसमें ऑब्जेक्ट्स के बिना ऑर्गन कन्स्ट्रक्टर या अंतिम फ़ील्ड हैं।

0

मैं कभी भी "क्लोन()" दृष्टिकोण का बड़ा प्रशंसक नहीं रहा हूं। कॉपी कंस्ट्रक्टर्स IMO अधिक सुरुचिपूर्ण होने लगते हैं:

public class Parent { 
    int x; 

    public Parent() { 
     super(); 
    } 

    public Parent(Parent other) { 
     super(); 
     this.x = other.x; 
    } 
} 

public class Child extends Parent { 
    int y; 

    public Child() { 
     super(); 
    } 

    public Child(Child other) { 
     super(other); 
     this.y = other.y; 
    } 
} 

ध्यान दें, यह भी यह करने के लिए सक्षम होने का अतिरिक्त लाभ है अगर आप की जरूरत है:

Parent p = new Parent(new Child(...)); 

आप निश्चित रूप से में उस व्यवहार को रोका जा सकता कंक्रीट तर्क के वर्ग प्रकार की जांच करके कन्स्ट्रक्टर, लेकिन मुझे नहीं लगता कि आपको ज्यादातर मामलों में क्यों आवश्यकता होगी।

+1

समस्या यह है कि कॉपी कन्स्ट्रक्टर polymorphism के साथ ठीक से सौदा नहीं करते हैं – user671786

संबंधित मुद्दे