2009-08-21 12 views
7

मान लें कि मेरे पास दो वर्ग हैं, जिन्हें ए और बी नाम दिया गया है, जो एक-दूसरे से जुड़े हुए हैं, यदि प्रत्येक वर्ग की ऑब्जेक्ट में दूसरे के संदर्भ में यह सबसे सुविधाजनक है। दूसरे शब्दों में, कक्षा ए में कक्षा बी का एक चर "बी" है। कक्षा बी में कक्षा ए का एक चर "ए" है। इस तरह, प्रत्येक वर्ग में कोड दूसरे वर्ग तक आसानी से पहुंच प्राप्त करता है।जावा: पारस्परिक, अंतिम कक्षा संदर्भ होना संभव है?

क्या इस संगठन को "अंतिम" बनाने के लिए कोई तरीका है? i.e. श्रेणी ए में परिवर्तनीय बी अंतिम और चर श्रेणी बी में अंतिम है? ऐसा लगता है कि एक निर्माता में इन संदर्भों को स्थापित करना (जैसा कि अंतिम खोजशब्द द्वारा आवश्यक होगा) को एक अजीब परिपत्र प्रकार के संदर्भ की आवश्यकता होती है।

यह व्यावहारिक से एक वैचारिक प्रश्न है। धन्यवाद!

उत्तर

6

जैसा कि एक अन्य पोस्टर ने इंगित किया है, दूसरे को बनाने के लिए जिम्मेदार कक्षाओं में से एक बनाकर और अन्य ऑब्जेक्ट के लिए स्वयं को उत्तीर्ण करने के लिए ऐसा करने के लिए संभव है।

हालांकि, यदि आप प्रथम श्रेणी के एक उदाहरण को दूसरे वर्ग के एक उदाहरण के अनुरूप करना चाहते हैं (जो ऐसा लगता है) तो यह संभावित मुद्दों पर खुद को उधार देता है। एक अन्य वस्तु संभावित रूप से दूसरी कक्षा के लिए कन्स्ट्रक्टर में पहली कक्षा के मौजूदा संदर्भ को पार कर सकती है, इस प्रकार एक अमान्य स्थिति की अनुमति देता है (दूसरी कक्षा का एक उदाहरण अब प्रथम श्रेणी के उदाहरण का संदर्भ है जो अलग-अलग का संदर्भ देता है दूसरी कक्षा का उदाहरण)।

जब आप मानते हैं कि द्वितीय श्रेणी के निर्माता पहले वर्ग के प्रारंभिक सदस्यों का संदर्भ नहीं दे सकते हैं तो अधिक संभावित समस्याएं उत्पन्न होती हैं।

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

+0

दो वर्गों का संयोजन करने से मदद नहीं मिलती है। सर्कुलर संदर्भ एक ही कक्षा की वस्तुओं के साथ अक्सर हो सकता है और अक्सर होता है। एक पेड़ में नोड्स पर विचार करें जहां प्रत्येक नोड के माता-पिता और उसके बच्चों के लिए अंतिम संदर्भ होता है, या अगले और पिछले नोड्स के अंतिम संदर्भ के साथ एक अपरिवर्तनीय दोगुनी-लिंक्ड सूची बनाने का प्रयास करता है। –

6

हां यह संभव है, यदि वर्ग में से कोई अन्य वर्ग का उदाहरण बनाने के लिए ज़िम्मेदार है। पहला कन्स्ट्रक्टर दूसरे वर्ग के पैरामीटर के रूप में स्वयं का एक उदाहरण पास कर सकता है।

public class A { 
    final B b; 
    public A() { 
     b = new B(this); 
    } 
    public B getB() { 
     return b; 
    } 
} 
public class B { 
    final A a; 
    public B(A a) { 
     this.a = a; 
    } 
} 
+4

हालांकि यह दृष्टिकोण काम कर सकता है, यह शायद खतरनाक है क्योंकि बी कन्स्ट्रक्टर को अभी तक पूरी तरह से निर्मित तत्व का संदर्भ प्राप्त नहीं हो रहा है। मान लीजिए, उदाहरण के लिए, ए में एक और क्षेत्र था जिसे * बी के बाद * प्रारंभ किया गया था, और बी कन्स्ट्रक्टर इसे एक्सेस करने का प्रयास करता है। यह एक अनियमित वस्तु प्राप्त होगी। बी बी कन्स्ट्रक्टर से ए के कॉलिंग विधियों के लिए भी जाता है, या यदि ए बाद में विस्तारित किया जाता है ... हो सकता है कि एक नया डिज़ाइन बेहतर विकल्प होगा। –

+0

थोड़ा अधिक संक्षेप में एक वर्ग को दूसरे की एक आंतरिक कक्षा है।(नोट: जैसा कि आपने 'बी' कन्स्ट्रक्टर सार्वजनिक बनाया है, एक अन्य पैकेज में एक और वर्ग 'ए' (या 'शून्य'!) के किसी भी उदाहरण के लिए एक और 'बी' बना सकता है।) –

+0

शायद दोनों को बनाना सबसे अच्छा तरीका होगा कन्स्ट्रक्टर पैकेज स्कोप, और ए प्रदान करने के लिए कुछ प्रकार की फैक्ट्री विधि प्रदान करते हैं। इस तरह कोई भी गलती से कक्षाओं का दुरुपयोग नहीं कर सकता है। – extraneon

1

यदि आप इस तरह के रूप में एक guice Di कंटेनर का उपयोग, आप स्पष्ट संदर्भ निर्माता के अंदर से गुजर बिना इस acieve कर सकते हैं - के रूप में पहले बताया त्रुटि प्रवण हो सकता है।

निर्भरता ए-बी और बी-ए घोषित करें और उनमें से एक को दूसरे वर्ग में इंजेक्ट करें। दोनों फ़ील्ड अंतिम होने की अनुमति देने के लिए गुस्सा कुछ जादू करेगा। मूल रूप से यह पहले एक प्रॉक्सी इंजेक्ट करेगा और बाद में अपने प्रतिनिधि को सेट करेगा।

क्या आपको इसके लिए कोड नमूना चाहिए?

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