मामले में आप कार्यान्वयन के बजाय एक्सटेंशन का उपयोग करने के लिए स्वतंत्र हैं, तो आप इस तरह से है कि कर सकता है:
public interface Thing { ... }
public abstract class Copyable {
public final Copyable copy() {
Copyable clone = createCopy();
if (clone.getClass() != getClass())
throw new RuntimeException("Copy has wrong type!");
return clone;
}
protected abstract Copyable createCopy();
}
और फिर इसे पसंद का उपयोग करें:
public class Test extends Copyable implements Thing {
public String content = null;
@Override
public Copyable createCopy() {
Test clone = new Test();
clone.content = this.content;
return clone;
}
}
/*code somewhere*/ {
Test t1 = new Test();
t1.content = "Hello world!";
Test t2 = (Test)t1.copy();
System.out.println(t2.content);
}
एक इस के साथ समस्या यह है, कि Copyable
एक इंटरफ़ेस नहीं है। हालांकि, इसका उपयोग बिना किसी दर्द के किया जा सकता है, जैसा कि उदाहरण में देखा गया है, लेकिन क्लास चेकिंग का उपयोग भाषा स्तर पर समर्थित नहीं है। दूसरे शब्दों के साथ, createCopy
अमूर्त विधि प्रतियों की कक्षा तक ही सीमित नहीं है, और प्रोग्रामर तक जो कुछ भी है, Copyable
कक्षा, या एक वर्ग, जो इसे विस्तारित करता है।
सकारात्मक पक्ष, यह है कि यदि आप ऑब्जेक्ट पर .copy()
पर कॉल करते हैं, तो उसे एक ऑब्जेक्ट को अपने जैसा ही वापस करना होगा। अपवाद के बजाय यदि आप चाहें तो null
वापस कर सकते हैं। फिर आपको अच्छा या कुछ भी नहीं मिला।
लेकिन, ईमानदार होने के लिए, मैं वास्तव में समझ में नहीं आता, क्यों आपकी createCopy
स्थानीय विधि में पैरामीटर है। यह हो सकता है तो एक स्थिर विधि ... altrough मैं कल्पना भी नहीं कर सकते हैं क्या है कि कोड ब्लॉक में जाना होगा:
static <X extends Thing> X copy(X object) { ... }
आप एक स्थिर सामान्य विधि के साथ अभ्यास जोड़ सकता है और परिणाम में थोड़ा और अधिक अनुकूल हो जाता है हो सकता है :
public interface Thing extends Cloneable {
public static <X extends Thing> X copy(X thing) {
Object clone = thing.clone();
if (clone.getClass() != getClass())
throw new RuntimeException("Copy has wrong type!");
return (X)clone;
}
}
public class ThingA implements Thing {
public Object clone() { ... }
}
/*code somewhere*/ {
ThingA a1 = new ThingA();
ThingA a2 = Thing.copy(a1);
}
फिर भी, क्लोनिंग विधि भाषा प्रतिबंध के बजाय एक अपवाद द्वारा नियंत्रित किया जाता है, लेकिन मुझे लगता है कि यह अब तक का सबसे अच्छा समाधान है।
यह अभी भी उसे वही करने की अनुमति देता है जो वह नहीं चाहता है। जेनेरिक आपको केवल एक प्रकार की कक्षा का उपयोग करने से नहीं रोकता है क्योंकि यह जेनेरिक उद्देश्य के विपरीत विपरीत होगा। – giorashc