2013-08-26 5 views
7

के लिए प्रतिबंधित सामान्य इंटरफ़ेस बनाएं, मैं उन दो वर्गों के लिए एक सामान्य इंटरफ़ेस बनाना चाहता हूं लेकिन मुझे यकीन नहीं है कि जेनरिक को सही तरीके से कैसे निर्दिष्ट किया जाए।अपनी कक्षा

public class ThingA implements Thing { 
    public ThingA createCopy(ThingA original); 
} 

public class ThingB implements Thing { 
    public ThingB createCopy(ThingB original); 
} 

मैंने इसे आजमाया।

public interface Thing<V extends Thing<V>> { 
    public V createCopy(V original); 

} 

लेकिन मैं अभी भी इस तरह की चीजें करने में सक्षम हूं, जिसकी अनुमति नहीं दी जानी चाहिए।

public class ThingB implements Thing<ThingA> { 
    public ThingA createCopy(ThingA original); 
} 

उत्तर

6

कोई this कुंजी-शब्द जेनरिक नहीं है (न ही विधियों के मानकों और वापसी मानों की घोषणा के लिए) और इस प्रकार आप वही नहीं कर सकते जो आप चाहते हैं।

दूसरे शब्दों में इंटरफ़ेस कक्षा में सभी विधियों को लगातार प्रकारों का उपयोग करने की अनुमति देगा, लेकिन वर्ग प्रकार को संदर्भित नहीं करेगा।

0

आप

public interface Thing<V> { 
    public V createCopy(V original); 
} 

के लिए देख रहे हैं? यदि नहीं, तो क्या आप "कक्षाओं के लिए एक सामान्य इंटरफेस बनाने" के लिए इसका क्या अर्थ है, इसके बारे में अधिक विस्तार से समझा सकते हैं?

+1

यह अभी भी उसे वही करने की अनुमति देता है जो वह नहीं चाहता है। जेनेरिक आपको केवल एक प्रकार की कक्षा का उपयोग करने से नहीं रोकता है क्योंकि यह जेनेरिक उद्देश्य के विपरीत विपरीत होगा। – giorashc

1

यह संभव नहीं है। और जेनिक्स के लिए यह नहीं है। जेनेरिक प्रकार सुरक्षा के लिए है, यानी कास्ट से परहेज करते हैं। अगर कोई कक्षा ThingB बनाता है जो Thing<ThingA> किसी भी तरह लागू करता है, तो बढ़िया। यह पूरी तरह से प्रकार सुरक्षित है। तुम क्यो फिकर करते हो? यह आप कैसे कर रहे हैं में बाधा डालती है?

0

मामले में आप कार्यान्वयन के बजाय एक्सटेंशन का उपयोग करने के लिए स्वतंत्र हैं, तो आप इस तरह से है कि कर सकता है:

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); 
} 

फिर भी, क्लोनिंग विधि भाषा प्रतिबंध के बजाय एक अपवाद द्वारा नियंत्रित किया जाता है, लेकिन मुझे लगता है कि यह अब तक का सबसे अच्छा समाधान है।

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