2008-09-16 13 views
8

मैंने सुना है कि एकल विरासत को धोखा देने और जावा में एकाधिक विरासत को लागू करने का एक तरीका है। क्या कोई यह जानता है कि इसे कैसे कार्यान्वित किया जाए (इंटरफ़ेस का उपयोग करके)?जावा में धोखा एकल विरासत?

बस जिज्ञासा से बाहर

;-)

+0

यह एक बहुत ही अलग विचार है। – Warrior

उत्तर

20

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

वैसे भी, जटिल कक्षाओं के लिए यह मुश्किल है, और आप स्थैतिक आयात (जावा 5 से) का उपयोग करके अधिकांश कार्यक्षमता प्राप्त कर सकते हैं। नौकरी साक्षात्कार और पब प्रश्नोत्तरी के लिए महान सवाल, हालांकि--)

+0

यही मुझे वास्तव में जरूरी है ... आंतरिक कक्षाओं का उपयोग करना .. धन्यवाद – Omnipotent

+1

यहां एक मामूली टाइपो है, मैं इसे ठीक कर दूंगा लेकिन मेरे पास अभी तक पर्याप्त प्रतिनिधि नहीं है । ' – TygerKrash

+0

@TygerKrash के रूप में उप वर्गों को बनाएं, आपको पदों को संपादित करने के लिए प्रतिनिधि की आवश्यकता नहीं है: एसई विकी की तरह होना है। –

0

जावा कई Inheritence समर्थन नहीं करता।

आप इसे कई इंटरफेस लागू करने के लिए प्राप्त कर सकते हैं और कुछ इसे समस्या के चारों ओर एक तरीके के रूप में देखते हैं। व्यक्तिगत रूप से मैंने अभी तक कई विरासत का उपयोग नहीं किया है, इसलिए मैं वास्तव में अपनी अपील को समझ नहीं सकता।

आम तौर पर जब कोई सी # या जावा के भीतर कई विरासत सुझाता है तो इस तथ्य के कारण कि वे सी ++ में 'कर सकते हैं'। मैं सिर्फ एक प्रशंसक हूं क्योंकि आप इसका मतलब नहीं कर सकते हैं '। सी # & जावा इसका समर्थन नहीं करता है, ऐसा करने के लिए इसे डिज़ाइन नहीं किया गया था, ऐसा करने का प्रयास क्यों करें। यह कहना नहीं है कि अद्वितीय मामले हैं जहां यह empoly करने के लिए एक वैध तकनीक है, बस कोड की आवश्यकता नहीं होने के लिए आमतौर पर प्रतिक्रिया की जा सकती है।

+0

आप शायद इसका मतलब है कि यह * एकाधिक * विरासत का समर्थन नहीं करता है। –

+0

स्काला में ट्राइट विरासत (अनिवार्य रूप से मिश्रित विरासत) कुछ तरीकों से पता चलता है जिसमें एकाधिक विरासत उपयोगी हो सकती है, हालांकि जावा की पसंद को लागू करने की पसंद समझ में नहीं आती है, क्योंकि कई कार्यान्वयन के कारण अनिवार्य रूप से जटिल होना समाप्त होता है। – Calum

4

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

यदि आप बस अपने प्रकार को कई अन्य प्रकारों की तरह "व्यवहार" करना चाहते हैं, तो आप जितना चाहें उतने इंटरफेस से प्राप्त कर सकते हैं; जाहिर है, आप इनसे कार्यान्वयन विवरण "उधार" नहीं ले सकते हैं।

1

interface एस का उपयोग करें। आप जितना चाहें उतना लागू कर सकते हैं। अगर आप वांछनीय हैं तो कार्यान्वयन कोड का पुन: उपयोग करने में सक्षम होने के लिए आप आमतौर पर Composite Pattern (GoF) पर कुछ संस्करण का उपयोग कर सकते हैं।

3

मेरा मानना ​​है कि मूल कारण यह है कि जावा एकाधिक विरासत का समर्थन नहीं करता है, सी # के समान है; सभी ऑब्जेक्ट अंततः ऑब्जेक्ट से व्युत्पन्न होते हैं और इसमें समान आधार वर्ग के कई पथ होते हैं जो कंपाइलर के लिए संदिग्ध होते हैं। अस्पष्ट == खराब, तो संकलक इसे अनुमति नहीं देता है।

इसके बजाय, आप प्रतिनिधिमंडल के माध्यम से एकाधिक विरासत अनुकरण कर सकते हैं। उदाहरण के लिए this article देखें।

+0

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

2

आप java.lang.reflect.Proxy उदाहरणों का उपयोग कर इसे थोड़ा धोखा दे सकते हैं (और मैं थोड़ा तनाव देता हूं)।

यह वास्तव में आपको अतिरिक्त इंटरफेस जोड़ने और रनटाइम पर किसी अन्य इंस्टेंस में अपनी कॉल को प्रतिनिधि करने की अनुमति देता है।

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

+0

हाँ, यह एक "साफ चाल" है लेकिन यह ऐसा कुछ नहीं है जिसे किसी को वास्तव में उत्पादन कोड में उपयोग करना चाहिए! – Calum

+0

लेकिन प्रॉक्सी का उपयोग करने के लिए आपको इंटरफेस की आवश्यकता है। ओपी: "... इंटरफेस का उपयोग कर बाहर ..." –

1

आपको कार्यान्वयन विरासत (कार्यान्वयन तंत्र की विरासत) से अंतरफलक विरासत (अनिवार्य रूप से विशेष सुविधाओं को प्रदान करने के लिए अनुबंध की विरासत) को अलग करने के लिए सावधान रहना होगा।

जावा औजार तंत्र द्वारा इंटरफ़ेस विरासत प्रदान करता है और आप कर सकते हैं कई इंटरफेस विरासत है।

कार्यान्वयन विरासत तंत्र बढ़ाता है और आपको केवल इसका एक संस्करण मिला है। क्या आप वास्तव में को कई कार्यान्वयन विरासत की आवश्यकता है? मैं शर्त लगाता हूं कि आप नहीं करते हैं, यह अप्रिय परिणामों से भरा हुआ है, जब तक कि आप एक एफिल प्रोग्रामर न हों।

1

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

0

मैं इस बारे में कुछ और सोच रहा था और महसूस किया कि गतिशील प्रॉक्सी काम करेगा (यह कैसे काम करने के लिए आरएमआई (प्रयुक्त?) है), यदि आप वास्तव में इस प्रकार की कार्यक्षमता चाहते हैं तो आप पहलू उन्मुख प्रोग्रामिंग को बेहतर तरीके से देखना बेहतर होगा (एओपी) AspectJ (eclipse.org/aspectj) जैसे कुछ का उपयोग कर।

इस तरह आप एक वर्ग में कई अलग-अलग पहलू प्राप्त कर सकते हैं, जिससे आपको छद्म विरासत विरासत विरासत के बिना छद्म मिश्रण विरासत मिलती है।

जैसा कि हर किसी ने इंगित किया है, एकाधिक विरासत की आवश्यकता/आवश्यकता आमतौर पर इंगित करती है कि आप सही परिप्रेक्ष्य से समस्या का सामना नहीं कर रहे हैं। शुरुआत के लिए "विरासत पर रचना पसंद करते हैं" के गोफ सिद्धांत को याद रखें!

4

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

0

इनर क्लासेस का उपयोग करके, सी ++ कभी-कभी यह भी पसंद करता है: Inner Class Idiom

-1

हाँ, आप कह सकते हैं कि यह एक चाल है और यह बहुत दिलचस्प है आप एक ही वर्ग के लिए कई वर्गों के वारिस नहीं कर सकता है लेकिन ऐसा लगता है

public class parents implements first, second{ 

} 

एक वर्ग के लिए कई इंटरफेस को लागू लेकिन याद करने के लिए संभव है, आपके पास इंटरफेस में घोषित विधियों को ओवरराइड करने के लिए।

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