2014-11-12 9 views
5

मैं करने के लिए एक पूरा जवाब साथ आने के लिए कोशिश कर रहा हूँ बनाम साथ इंटरफेस:जावा 8 - डिफ़ॉल्ट तरीकों सार कक्षाएं

"। क्यों/जब एक अंतरफलक बजाय एक अमूर्त वर्ग का उपयोग करें"

और निम्न पर सत्यापन/सुझावों की तलाश में।

इसका एक जवाब है,

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

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

फिर, इस संदर्भ में, क्यू आता है:

"जावा 8 के बाद से, इंटरफेस default method कार्यान्वयन को परिभाषित कर सकते क्यों मैं इंटरफ़ेस के बजाय में डिफ़ॉल्ट विधि (रों) लिखना नहीं होता। ? एक अमूर्त वर्ग है कि उन विधि (रों) लागू करता "

इसका जवाब होगा:

" एक कारण यह है कि: इंटरफ़ेस विधियां सभी सार्वजनिक हैं, फ़ील्ड सदस्य सभी स्थिरांक हैं (अंतिम & सार्वजनिक)। आप विधियों के एक्सेस विशेषाधिकारों को प्रतिबंधित करना चाहते हैं और/या उन्हें गैर-स्थिर स्थिति पर संचालित करना चाहते हैं।

दूसरा यह है: एक वंश वर्ग सुपर द्वारा सर क्लास विधि (ओं) पर कॉल कर सकता है, जबकि यह डिफ़ॉल्ट इंटरफ़ेस विधियों पर ऐसा नहीं कर सकता है। इसके अलावा, इंटरफेस में वंशजों द्वारा कोई कन्स्ट्रक्टर नहीं लगाया जाना चाहिए।

शेष कारण उपर्युक्त जावा 8 में समान हैं। ? "

इन ऊपर के अलावा, मैं क्यों नहीं बल्कि विशेष रूप से अब मैं डिफ़ॉल्ट इंटरफ़ेस तरीकों है कि एक अंतरफलक से एक अमूर्त वर्ग के लिए जाना होगा के बाद से जावा 8

कृपया ध्यान दें: मैं Java 8 default methods vs. non-abstract methods in abstract classes देखा है और Interface with default methods vs Abstract class in Java 8 कुछ अन्य उपयोगी विचार विमर्श के साथ। यह क्यू बल्कि के बारे में क्यों इसका उल्टा से एक अंतरफलक से अधिक एक अमूर्त वर्ग का फैसला किया।

TIA है।

+3

हालांकि मुझे लगता है कि यह एक वैध सवाल है, मुझे यकीन नहीं है कि यह स्टैक ओवरफ्लो के लिए स्थैतिक है या नहीं। आप [प्रोग्रामर.एसई] (programmers.stackexchange.com) को आजमा सकते हैं। – nhaarman

उत्तर

5

इंटरफ़ेस पर एक सार वर्ग चुनने के कुछ कारण यहां दिए गए हैं। जिन लोगों को आप सूचीबद्ध करते हैं - निजी फ़ील्ड इत्यादि कुछ प्रमुख हैं। ये कुछ और सूक्ष्म हैं

  • स्पष्टता टाइप करें। आप केवल एक वर्ग का विस्तार कर सकते हैं। इससे यह स्पष्ट हो जाता है कि आपकी वस्तु इसका उपयोग कैसे करती है।
  • हीरा समस्या। हीरा समस्या से बचने में मदद के लिए आपको इंटरफ़ेस में सभी डिफ़ॉल्ट विधियों को लागू करना होगा। यदि इंटरफेस संग्रह है, तो यह एक बड़ा दर्द हो सकता है क्योंकि उनमें से एक अरब हैं। एक अमूर्त वर्ग के साथ, आप केवल
  • जावा 8 में, लैम्ब्डा अभिव्यक्तियां हैं, और कार्यान्वित करने के तरीके के साथ एक इंटरफेस के चारों ओर गुज़रने की पुरानी दिनचर्या को केवल ओवरराइट किया गया है। फिर भी, जब आप एक डिफ़ॉल्ट विधि के साथ एक अंतरफलक देखो, यह कर सकते हैं तरीके से व्याख्या की आप का इरादा नहीं हो सकता है

यहाँ ओरेकल क्या इस विषय पर क्या कहना है है:

कौन का उपयोग करना चाहिए, सार कक्षाएं या इंटरफेस?

  • आप कई निकट से संबंधित वर्गों के बीच कोड साझा करना चाहते हैं: यदि इनमें से कोई कथन को अपनी स्थिति लागू सार वर्गों का उपयोग पर विचार करें।
  • आप उम्मीद करते हैं कि आपके सार वर्ग को बढ़ाने वाले वर्गों में कई सामान्य विधियां या फ़ील्ड हैं, या सार्वजनिक (जैसे संरक्षित और निजी) के अलावा एक्सेस संशोधक की आवश्यकता है।
  • आप गैर स्थैतिक या गैर-अंतिम फ़ील्ड घोषित करना चाहते हैं। यह आपको उन विधियों को परिभाषित करने में सक्षम बनाता है जो ऑब्जेक्ट की स्थिति को एक्सेस और संशोधित कर सकते हैं, जिनके वे संबंधित हैं।

इस लेख में, Orace दो प्रकार प्रणालियों के बीच भेद https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

संपादित "हीरे समस्या" बुलेट समस्या यहाँ वर्णित है स्पष्ट करने के लिए (और अन्य कई स्थानों) का बचाव http://www.lambdafaq.org/what-about-the-diamond-problem/

समस्या तब होती है जब आप एक ही विधि घोषित करने वाले दो स्थानों से प्राप्त होते हैं, और आपको फ़ंक्शन ca को हल करते समय एक चुनना होता है डालूँगा। जावा 7 में यह कभी भी कोई मुद्दा नहीं था, क्योंकि आप केवल एक वर्ग का विस्तार कर सकते थे और इंटरफेस के पास कोई तरीका नहीं था। (http://blog.loxal.net/2013/05/java-8-default-interface.html से)

हीरा समस्या एक पूर्वता का क्रम एक कार्यान्वयन प्रयोग किया जाता है नहीं है पता करने के लिए:

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

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

+0

क्या आप हीरे की समस्या पर अधिक विशिष्ट हो सकते हैं – Roam

1

संक्षिप्त उत्तर:

  1. एक वर्ग ठीक एक वर्ग बढ़ा सकता है।
  2. एक कक्षा किसी भी इंटरफेस को लागू कर सकती है।
7

डिफ़ॉल्ट विधियों के साथ इंटरफ़ेस केवल व्यवहार को परिभाषित कर सकता है जबकि सार कक्षाओं में एक राज्य हो सकता है।

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

अमूर्त कक्षाओं का एक और उपयोग केस यह है कि यदि आप विधियों जैसे equals या toString पर ओवरराइड करना चाहते हैं। यह डिफ़ॉल्ट तरीकों के माध्यम से नहीं किया जा सकता है।

0

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

  • सार वर्ग कंस्ट्रक्टर्स हो सकता है, लेकिन इंटरफ़ेस नहीं कर सकता।
  • सार वर्ग केवल एक वर्ग से का उत्तराधिकारी हो सकता है और इंटरफेस को कार्यान्वित कर सकता है लेकिन एक इंटरफेस केवल कई इंटरफेस का विस्तार कर सकता है।

  • सार वर्ग विशेषताओं भी क्षणिक हो सकता है/अस्थिर

  • सार वर्ग तरीकों भी अंतिम/स्थिर/सिंक्रनाइज़/देशी

  • इंटरफेस हो सकता है तरीकों भी डिफ़ॉल्ट किया जा सकता है या कार्यान्वयन के साथ स्थिर। (डिफ़ॉल्ट और स्थैतिक दोनों नहीं हो सकता है।)

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