2010-10-16 12 views
6

विषय में सामान्य सवाल का एक व्यावहारिक उदाहरण के रूप में, मैं,इंटरफेस कार्यान्वयन सुपर-क्लास

public boolean containsAll(Iterable<?> c) { /* ... */ } 

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

हालांकि, ग्रहण कोई रास्ता नहीं कहता है (केवल जावैक सीधे प्रयास नहीं किया है) - क्या कोई इसके कारण बता सकता है? मुझे यकीन है कि इस कल्पना में कुछ ऐसा है जो इसे बनाता है, लेकिन मैं आवश्यकता के लिए प्रेरणा को भी समझना चाहता हूं। या क्या मुझे Iterable<?> की तरह कुछ याद आ रहा है Collection<?> का सुपरक्लास नहीं है?

एक साइड सवाल के रूप में - दिया गया है कि मैं दो तरीकों की घोषणा कर रहा हूं Iterable हस्ताक्षर के साथ विधि हमेशा Collection तर्क के साथ कॉल पर प्राथमिकता दी जाएगी?

ग्रहण त्रुटि:

अगर मैं Collection हस्ताक्षर के साथ विधि, बस छोड़ने को दूर Iterable एक (त्रुटि के बाद देखें), मैं निम्नलिखित मिल:

The type BitPowerSet must implement the inherited abstract method Set<Long>.containsAll(Collection<?>)

सटीक कार्यान्वयन किया जा रहा है :

@Override public boolean containsAll(Collection<?> c) { 
    for (Object o : c) if (!contains(o)) return false; 
    return true; 
} 
public boolean containsAll(Iterable<?> c) { 
    for (Object o : c) if (!contains(o)) return false; 
    return true; 
} 
+0

क्या आप एक त्रुटि पोस्ट कर सकते हैं ग्रहण आपको दे रहा है? आईडीईए में मेरे लिए काम करता है। –

+0

@ निकिता: संपादित किया गया। Soooo ... यह सिर्फ एक ग्रहण चीज हो सकता है? – Carl

+0

यह एक शब्दावली दुःस्वप्न है। मैं ऐसी चुनौतियों से दूर भाग गया। – skaffman

उत्तर

2

क्यों जावा इस प्रतिबंध है के रूप में मेरा अनुमान है, कहते हैं कि तुम है:

class A { 
    void foo(String s) { ... } 
} 

class B extends A { 
    // Note generalized type 
    @Override void foo(Object s) { ... } 
} 

अब अगर आप class C extends B है और यह foo ओवरराइड करने के लिए चाहता है, यह स्पष्ट नहीं है क्या तर्क यह लेना चाहिए।

कहते हैं उदाहरण के लिए C पहली बार में सीधे एक बढ़ाया, void foo(String s) अधिभावी, और फिर इसे इस मामले में बी का विस्तार करने के foo के सी के मौजूदा ओवरराइड अमान्य हो जाएगा, क्योंकि बी के foo सभी Object रों संभाल करने में सक्षम होना चाहिए, नहीं बदला गया था बस String एस।

+0

आह, यह एक समझदार स्पष्टीकरण प्रतीत होता है - इंटरफ़ेस को चौड़ा करना मांग करेगा कि उप वर्ग विस्तृत इंटरफ़ेस बनाए रखें। फिर भी, ऐसा लगता है कि इसे अनुमति दी जानी चाहिए - आम तौर पर, सबक्लास को इंटरफेस को संकीर्ण करने की अनुमति नहीं है। – Carl

+0

यह संभवतः वर्चुअल टेबल के डिज़ाइन को स्पष्ट करने के लिए बनाता है कि इसमें सभी विधियों का सटीक हस्ताक्षर है। या हो सकता है कि वे बस यह समझ सकें कि अगर वे इसे पर्याप्त रूप से आगे बढ़ाते हैं तो वे इसे काम कर सकते हैं, लेकिन एक आकर्षक आवश्यकता को नहीं देखा और इसे छोड़ दिया। – oksayt

+0

मुझे कुछ याद आ रही है - क्या वह उदाहरण काम करना चाहिए? @ ओवरराइड एनोटेशन पर मुझे "विधि अपने सुपरक्लास से विधि ओवरराइड नहीं करती है"। – Amalgovinus

5

चूंकि आप जिस इंटरफेस को लागू कर रहे हैं, वह (सार) घोषित करता है विधि containsAll(Collection<?>), आपको इसे इस सटीक हस्ताक्षर के साथ कार्यान्वित करना होगा। जावा आपको मूल से अधिक व्यापक पैरामीटर प्रकार के साथ एक विधि को कार्यान्वित/ओवरराइड करने की अनुमति नहीं देता है। यही कारण है कि जब आप Collection हस्ताक्षर के साथ अपनी विधि पर टिप्पणी करते हैं तो आपको वह त्रुटि मिलती है जो आप दिखाते हैं।

आप जिस त्रुटि को टिप्पणी नहीं करते हैं, उसे प्राप्त करने के लिए आप जिस अन्य त्रुटि का दावा करते हैं, उसे नहीं दिखाते हैं, लेकिन मुझे लगता है कि इसे संदिग्ध विधि ओवरलोडिंग के साथ कुछ करना पड़ सकता है।

+0

जब कोई विधि टिप्पणी नहीं की जाती है तो कोई त्रुटि नहीं होती है। केवल तभी जब 'संग्रह' हस्ताक्षर वाला कोई व्यक्ति होता है। – Carl

+0

इसके अलावा, इस मामले में कोई अंतर्दृष्टि क्यों है? क्या यह @ oksayt के जवाब के साथ है? – Carl

+0

@ करल, तुम्हारा मतलब है कि जावा क्यों डिज़ाइन किया गया है? हो सकता है। –

0

तर्क प्रकार विधि हस्ताक्षर का हिस्सा हैं, इसलिए जेवीएम को ओवरराइड खोजने के लिए एक ही हस्ताक्षर के साथ एक विधि की आवश्यकता होती है। एक युक्त सभी (Iterable) में सभी (संग्रह) से भिन्न हस्ताक्षर होगा।

यदि मुझे सही याद है कि संकलक को इस सीमा के बावजूद जेनेरिक काम करने के लिए कुछ कामकाज का उपयोग करना है।

आपके दूसरे प्रश्न के लिए, कंपाइलर संग्रह तर्क पसंद करेगा क्योंकि यह इटेबल के उप-प्रकार है, इससे संग्रह विधि को इटेबल एक से अधिक विशिष्ट बनाता है।

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