क्लोनिंग एक बुनियादी प्रोग्रामिंग प्रतिमान है। तथ्य यह है कि जावा ने इसे कई तरीकों से खराब तरीके से लागू किया हो सकता है क्लोनिंग की आवश्यकता को कम नहीं करता है। और, क्लोनिंग को लागू करना आसान है जो काम करेगा लेकिन आप इसे काम करना चाहते हैं, उथले, गहरे, मिश्रित, जो भी हो। आप फ़ंक्शन के लिए नाम क्लोन का उपयोग भी कर सकते हैं और यदि आप चाहें तो क्लोन करने योग्य लागू नहीं कर सकते हैं।
मान लीजिए कि मेरे पास ए, बी, और सी की कक्षाएं हैं, जहां बी और सी ए से प्राप्त होते हैं। यदि मेरे पास इस प्रकार की वस्तुओं की सूची है:
ArrayList<A> list1;
अब, उस सूची में ए, बी या सी प्रकार की वस्तुएं हो सकती हैं। आप नहीं जानते कि वस्तुएं किस प्रकार की हैं। इसलिए, आप सूची को इस तरह से कॉपी नहीं कर सकते हैं:
ArrayList<A> list2 = new ArrayList<A>();
for(A a : list1) {
list2.add(new A(a));
}
यदि वस्तु वास्तव में बी या सी प्रकार की है, तो आपको सही कॉपी नहीं मिलेगी। और, क्या होगा अगर A सार है? अब, कुछ लोगों ने यह सुझाव दिया है:
ArrayList<A> list2 = new ArrayList<A>();
for(A a : list1) {
if(a instanceof A) {
list2.add(new A(a));
} else if(a instanceof B) {
list2.add(new B(a));
} else if(a instanceof C) {
list2.add(new C(a));
}
}
यह एक बहुत ही बुरा विचार है। यदि आप एक नया व्युत्पन्न प्रकार जोड़ते हैं तो क्या होगा? क्या होगा यदि बी या सी किसी अन्य पैकेज में हैं और आपके पास इस कक्षा में उनकी पहुंच नहीं है?
आप यह करना चाहते हैं:
ArrayList<A> list2 = new ArrayList<A>();
for(A a : list1) {
list2.add(a.clone());
}
बहुत से लोगों ने संकेत दिया है कि क्लोन का मूल जावा कार्यान्वयन समस्याग्रस्त क्यों है। लेकिन, यह आसानी से इस तरह से दूर हो जाएगा:
कक्षा ए में:
public A clone() {
return new A(this);
}
कक्षा B में:
@Override
public B clone() {
return new B(this);
}
कक्षा सी में:
@Override
public C clone() {
return new C(this):
}
मैं Cloneable को लागू नहीं कर रहा हूं, बस एक ही फ़ंक्शन नाम का उपयोग कर रहा हूं। यदि आपको यह पसंद नहीं है, तो इसे कुछ और नाम दें।