2011-11-03 13 views
19

आईई। निम्नलिखित "चक्रीय निर्भरता" क्यों संभव नहीं है?जावा आंतरिक आंतरिक इंटरफेस की विरासत को प्रतिबंधित क्यों कर रहा है?

public class Something implements Behavior { 
    public interface Behavior { 
     // ... 
    } 
} 

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

+0

क्लासलोडर की तरह लगता है कि कक्षा को पहले इंटरफ़ेस को जानने के लिए कक्षा को पढ़ना होगा, जिसे कक्षा को पहली जगह परिभाषित करने की आवश्यकता है ... मुझे क्लासलोडिंग का विवरण नहीं पता है, लेकिन यह बहुत स्पष्ट प्रतीत होता है। –

+2

@donneo: चूंकि संकलक "चक्रीय निर्भरता" के बारे में शिकायत करता है, मुझे लगता है कि यह पहले से ही जानता है कि आंतरिक वर्ग में किस प्रकार परिभाषित किया गया है। यह सिर्फ मेरे लिए मनमानी प्रतिबंध की तरह लगता है। –

+0

@ फिलिप: आप किस कंपाइलर का उपयोग कर रहे हैं? मेरा (ओरेकल जेडीके 6 और 7) केवल शिकायत करता है कि वे "प्रतीक नहीं ढूंढ सकते"। इसके अलावा: अच्छा सवाल, चूंकि एक नेस्टेड इंटरफेस किसी भी तकनीकी तरीके से बाहरी वर्ग पर वास्तव में * भरोसा नहीं करता है, यह * कानूनी हो सकता है। –

उत्तर

11

प्रासंगिक नियम:

http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.4

एक वर्ग सी सीधे एक प्रकार टी पर निर्भर करता है, तो टी फैली या सी के खंड को लागू करता है या तो एक सुपर क्लास या superinterface के रूप में बताया गया है , या एक superclass या superinterface नाम के योग्यता के रूप में।

http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.1.3

एक इंटरफेस मैं सीधे एक प्रकार टी पर निर्भर करता है, तो टी में उल्लेख किया है मैं या तो के खंड फैली एक superinterface रूप में या एक superinterface नाम के भीतर एक क्वालीफायर के रूप में किया जाता है।

इसलिए अगर A extends|implements B.C, एक C और B दोनों पर निर्भर करता है। एसपीसी फिर परिपत्र निर्भरताओं को मना करता है।

निर्भरता में B सहित प्रेरणा अस्पष्ट है। जैसा कि आपने उल्लेख किया है, यदि B.C को शीर्ष स्तर C2 पर प्रचारित किया गया है, तो टाइप सिस्टम के संबंध में बहुत अलग नहीं है, तो A extends C2 क्यों ठीक है, लेकिन A extends B.C नहीं है?एक नेस्टेड प्रकार माना जाता है B.C में B की सामग्री के लिए कुछ प्राइवेटेड पहुंच है, लेकिन मुझे स्पेस में कुछ भी नहीं मिला है जो A extends B.C परेशानी बनाता है।

एकमात्र समस्या यह है कि C एक आंतरिक वर्ग है। मान लीजिए B=A, A extends A.C को प्रतिबंधित किया जाना चाहिए, क्योंकि "संलग्न उदाहरण" की परिपत्र निर्भरता है। यह संभवतः असली प्रेरणा है - आंतरिक वर्ग को विरासत में प्राप्त करने से बाहरी वर्ग को मना करना। वास्तविक नियम अधिक सामान्यीकृत होते हैं, क्योंकि वे सरल होते हैं, और गैर-आंतरिक वर्गों के लिए भी वैसे भी अच्छा अर्थ बनाते हैं।

10

कल्पना करें कि आप कंपाइलर हैं।

हम आपको कुछ कक्षा बनाने के लिए कह रहे हैं। यह वर्ग व्यवहार लागू करता है ... लेकिन व्यवहार अभी तक मौजूद नहीं है क्योंकि कुछ पहले से पंजीकृत नहीं है ...

क्या आप समस्या को समझते हैं?

कक्षा को बॉक्स के रूप में देखें जिसमें चीजें हैं। व्यवहार कुछ बॉक्स में निहित है। लेकिन कुछ मौजूद नहीं है।

+3

यदि प्रश्न सी ++ के बारे में था तो यह एक वैध जवाब होगा। –

+1

हां, लेकिन व्यवहार एक इंटरफ़ेस है और इस प्रकार कुछ के निर्माण पर निर्भर नहीं है। –

+0

हां यह करता है, क्योंकि वह इंटरफ़ेस कुछ का हिस्सा है। व्यवहार का संदर्भ देने से पहले कुछ अस्तित्व में होना चाहिए, लेकिन व्यवहार को संदर्भित करने के लिए आपको कुछ बनाने की आवश्यकता है। –

0

साधारण तथ्य यह है कि भाषा चश्मा मना कर देता है, यह पर्याप्त होना चाहिए।

कुछ कारणों मैं के बारे में सोच सकता है:

  • यह उपयोगी नहीं होगा।

  • किसी भी कारण से आप इसका उपयोग करना चाहेंगे, मुझे यकीन है कि बेहतर विकल्प मौजूद हैं।

  • बाल वर्गों को बेस क्लास का विस्तार करना चाहिए, तो आप अपने बच्चे के अंदर बेस क्लास क्यों घोषित करेंगे?

  • यह एक अलग वर्ग होने के साथ-साथ आपके आंतरिक वर्ग का विस्तार करने वाला प्रतिद्वंद्वी होगा। कल्पना में

+0

यह उन मामलों के लिए उपयोगी होगा जिन्हें हमें एक अलग वर्ग में जाने के लिए कॉलबैक इंटरफ़ेस की आवश्यकता होती है। – ismailarilik