जब उपयोग करने के लिए: जावा 8 + इंटरफ़ेस डिफ़ॉल्ट विधि, बनाम सार विधि


540

जावा 8 डिफॉल्ट मेथड्स नामक विधियों में डिफ़ॉल्ट कार्यान्वयन के लिए अनुमति देता है ।

मैं इस बात को लेकर असमंजस में हूं कि मैं कब ( ) के interface default methodबजाय उस तरह का प्रयोग करूंगा ।abstract classabstract method(s)

तो डिफ़ॉल्ट तरीकों के साथ इंटरफ़ेस का उपयोग कब किया जाना चाहिए और एक सार वर्ग (अमूर्त पद्धति (ओं) के साथ कब इस्तेमाल किया जाना चाहिए? क्या अमूर्त वर्ग अभी भी उस परिदृश्य में उपयोगी हैं?


38
हो सकता है कि आप अभी भी इंटरफेस में फ़ील्ड, निजी तरीके आदि नहीं रख सकते, जबकि आप अमूर्त वर्ग में हो सकते हैं?
sp00m

2
मैं पहले इस विषय के बारे में सोच रहा था, अब मैं स्पष्ट हूं। @ नरेन्द्र पठाई को धन्यवाद। मैं एक ही विषय के संबंध में आपके द्वारा पूछे गए एक और सूत्र का लिंक जोड़ना चाहूंगा, क्योंकि ये दोनों मेरे संदेह थे। stackoverflow.com/questions/19998309/…
आशुतोष रंजन

आप इस पर एक अच्छी पोस्ट यहाँ पा सकते हैं: blog.codefx.org/java/everything-about-default-methods
Fabri Pautasso

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

@DaBlick आप HashMap के माध्यम से एक इंटरफ़ेस में राज्य की समस्या को हल नहीं कर सकते। Ex: यदि आप एक वर्ग फू चाहते हैं जो int a, b, String c रखती है। और आप चाहते हैं कि उनके पास राज्य है, Fash ऑब्जेक्ट का एक </ * नाम * बनाएं / स्ट्रिंग, / * फ़ील्ड्स का नक्शा * / Hashmap </ * नाम विशिष्ट फ़ील्ड * / स्ट्रिंग, / * फ़ील्ड मान * / ऑब्जेक्ट >> मैप । जब आप सैद्धांतिक वर्ग फू को "तत्काल" करना चाहते हैं, तो आपके पास विधि, इंस्टेंटिअट (स्ट्रिंग nameOfFoo) है, जो map.put (nameOfFoo, फ़ील्ड्स) करता है जहाँ फ़ील्ड एक HashMap <स्ट्रिंग, ऑब्जेक्ट "फ़ील्ड" ("a", नया है पूर्णांक ( "5")); फ़ील्ड.पुट ("बी", नया इंट ("6")); फ़ील्ड.पुट ("सी", "ब्लाह"));
जॉर्ज जेवियर

जवाबों:


307

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

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

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

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


34
इस तर्क के द्वारा, अगली चीज़ जो वे जोड़ते हैं वह है डिफ़ॉल्ट विधि घोषणाएँ। मैं अभी भी इसके बारे में अनिश्चित हूं, यह सुविधा मुझे हैक की तरह लगती है जो दुरुपयोग के लिए हर किसी के सामने आ रही है।
पैंथर

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

7
@Anuroop केवल डिफ़ॉल्ट रूप से नहीं --- यही एकमात्र विकल्प है। इंटरफेस उदाहरण राज्य की घोषणा नहीं कर सकते, यही वजह है कि अमूर्त कक्षाएं यहां रहने के लिए हैं।
मार्को टोपोलनिक

2
@PhilipRego सार तरीके कुछ भी कॉल नहीं करते हैं क्योंकि उनका कोई कार्यान्वयन नहीं है। एक कक्षा में लागू किए गए तरीके कक्षा की स्थिति (उदाहरण के चर) तक पहुंच सकते हैं। इंटरफेस उन्हें घोषित नहीं कर सकते, इसलिए डिफ़ॉल्ट तरीके उन्हें एक्सेस नहीं कर सकते। उन्हें एक कार्यान्वित विधि प्रदान करने वाले वर्ग पर निर्भर रहना पड़ता है जो राज्य तक पहुंचता है।
मार्को टोपोलनिक

2
मार्को टोपोलनिक, आपका उत्तर मृत है। लेकिन मैं आपके उत्तर के लिए एक अद्यतन की सिफारिश करना चाहूंगा। आप जोड़ना चाह सकते हैं कि डिफ़ॉल्ट विधियों की सुंदरता यह है कि, यदि इंटरफ़ेस नए डिफ़ॉल्ट तरीकों को जोड़ता है, तो उस इंटरफ़ेस का आपका पिछला कार्यान्वयन नहीं टूटेगा। यह जावा 8 से पहले सच नहीं था।
hfontanez

125

कुछ तकनीकी अंतर हैं। सार वर्ग अभी भी जावा 8 इंटरफेस की तुलना में अधिक कर सकते हैं:

  1. सार वर्ग में एक कंस्ट्रक्टर हो सकता है।
  2. सार वर्ग अधिक संरचित हैं और एक राज्य को धारण कर सकते हैं।

अवधारणात्मक रूप से, बचाव के तरीकों का मुख्य उद्देश्य जावा 8 में नई सुविधाओं (लैम्बडा-फ़ंक्शंस) की शुरूआत के बाद एक पिछड़ी संगतता है।


20
यह उत्तर वास्तव में सही है और विशेष रूप से समझ में आता है "संकल्पनात्मक रूप से, डिफेंडर विधियों का मुख्य उद्देश्य एक पिछड़ी संगतता है"
कोशिश

1
: @UnKnown यह पेज अधिक जान सकेंगे docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
बर्नी

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

3
बिंदु संख्या के बारे में अधिक सूक्ष्म बिंदु। 2 के बारे में ऊपर "पकड़ राज्य है यह कर सकते हैं"। एब्सट्रैक्ट क्लासेस स्टेट को होल्ड कर सकते हैं जिसे बाद में बदला जा सकता है। अंतर राज्य भी धारण कर सकते हैं लेकिन एक बार राज्य के निर्माण के बाद सौंपा जाता है तो राज्य को बदला नहीं जा सकता।
अनुरुप

3
@Anuroop मैं public static finalएक इंटरफ़ेस के क्षेत्र का वर्णन "राज्य" के रूप में नहीं करूंगा । staticभाग का मतलब है कि सभी पर एक विशेष उदाहरण से संबंधित नहीं the're। उन्हें कक्षा तात्कालिकता पर सौंपा गया है , जो उदाहरण के निर्माण के बाद के समान नहीं है ।
geronimo

65

इस लेख में इसका वर्णन किया जा रहा है । forEachसंग्रह के बारे में सोचो ।

List<?> list = 
list.forEach(…);

ForEach अभी तक java.util.Listऔर न ही java.util.Collectionइंटरफ़ेस द्वारा घोषित नहीं किया गया है। एक स्पष्ट समाधान केवल मौजूदा इंटरफ़ेस में नई पद्धति को जोड़ना और जहां JDK में आवश्यक है वहां कार्यान्वयन प्रदान करना होगा। हालांकि, एक बार प्रकाशित होने के बाद, मौजूदा कार्यान्वयन को तोड़ने के बिना एक इंटरफ़ेस में तरीकों को जोड़ना असंभव है।

डिफ़ॉल्ट तरीकों को लाने का लाभ यह है कि अब इंटरफ़ेस में एक नई डिफ़ॉल्ट विधि जोड़ना संभव है और यह कार्यान्वयन को नहीं तोड़ता है।


1
'मौजूदा कार्यान्वयन को तोड़े बिना एक इंटरफ़ेस में तरीकों को जोड़ना असंभव है' - क्या यह है?
एंड्रे चेशेव

26
@AndreyChaschev यदि आप इंटरफ़ेस में एक नई विधि जोड़ते हैं, तो सभी कार्यान्वयनकर्ताओं को उस नई विधि को लागू करना होगा। इसलिए यह मौजूदा कार्यान्वयन को तोड़ता है।
मार्को टोपोलनिक

4
@MarkoTopolnik धन्यवाद, याद किया। बस यह उल्लेख करने का एक तरीका है कि आंशिक रूप से इससे बचने का एक तरीका है - इस पद्धति को डिफ़ॉल्ट अमूर्त कार्यान्वयन में प्रस्तुत करके। इस उदाहरण के लिए यह AbstractList::forEachएक फेंक दिया जाएगा UnsupportedOperationException
एंड्री चेशेव

3
@AndreyChaschev हाँ, यह पुराना तरीका था (khm ... वर्तमान तरीका है :), इस कमी के साथ कि यह प्रदान करने वाले को अमूर्त प्रदान करने वाले अमूर्त कार्यान्वयन से प्रतिबंधित करता है।
मार्को टोपोलनिक

अगर ऐसा होता है तो मैं नहीं टूटूंगा, समय से पहले, सभी कार्यान्वयन में वह विधि शामिल है। जो संभव नहीं है लेकिन संभव है।
जॉर्ज जेवियर

19

ये दोनों काफी अलग हैं:

डिफ़ॉल्ट विधियाँ अपने राज्य को बदलने के बिना मौजूदा वर्गों में बाहरी कार्यक्षमता को जोड़ने के लिए हैं

और अमूर्त वर्ग एक सामान्य प्रकार की विरासत हैं, वे सामान्य वर्ग हैं जिन्हें विस्तारित करने का इरादा है।


18

जैसा कि इस लेख में बताया गया है ,

जावा 8 में सार कक्षाएं बनाम इंटरफेस

डिफ़ॉल्ट विधि की शुरुआत करने के बाद, ऐसा लगता है कि इंटरफेस और अमूर्त वर्ग समान हैं। हालांकि, वे अभी भी जावा 8 में अलग अवधारणा हैं।

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


मेरा मानना ​​है कि Abstract क्लास में कंस्ट्रक्टर होता है जिसे इंटरफेस के विपरीत परिभाषित किया जा सकता है। जावा 8 में भी वे दोनों एक दूसरे के कारण अलग-अलग हैं।
हेमंत लीला

1
एक सार वर्ग के पास एक कंस्ट्रक्टर क्यों होता है अगर इसे तत्काल नहीं किया जा सकता है?
जॉर्ज जेवियर

हम चाइल्ड क्लास से सुपर () कह सकते हैं जो एब्सट्रैक्ट क्लास के कंस्ट्रक्टर को बुलाएगा। यह एब्सट्रैक्ट क्लास की स्थिति को प्रभावित करता है।
सुजय मोहन

14

आपकी क्वेरी के बारे में

तो डिफ़ॉल्ट तरीकों के साथ इंटरफ़ेस का उपयोग कब किया जाना चाहिए और एक सार वर्ग का उपयोग कब किया जाना चाहिए? क्या अमूर्त वर्ग अभी भी उस परिदृश्य में उपयोगी हैं?

जावा प्रलेखन सही उत्तर प्रदान करता है।

इंटरफेसेस की तुलना में एब्सट्रैक्ट क्लासेस:

अमूर्त कक्षाएं इंटरफेस के समान हैं। आप उन्हें तुरंत नहीं कर सकते हैं, और उनमें कार्यान्वयन के साथ या बिना घोषित तरीकों का मिश्रण हो सकता है।

हालांकि, अमूर्त कक्षाओं के साथ, आप उन क्षेत्रों की घोषणा कर सकते हैं जो स्थिर और अंतिम नहीं हैं, और सार्वजनिक, संरक्षित और निजी ठोस तरीकों को परिभाषित करते हैं।

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

एसई पोस्ट के नीचे उनमें से प्रत्येक के लिए मामलों का उपयोग किया गया है:

इंटरफ़ेस और अमूर्त वर्ग के बीच अंतर क्या है?

क्या अमूर्त वर्ग अभी भी उस परिदृश्य में उपयोगी हैं?

हाँ। वे अभी भी उपयोगी हैं। वे गैर स्थिर, गैर अंतिम तरीकों शामिल कर सकते हैं और विशेषताओं ( रक्षा की, जनता के लिए इसके अलावा में निजी ) है, जो भी जावा-8 इंटरफेस के साथ संभव नहीं है।


अब इंटरफेस में निजी तरीके भी हैं howtodoinjava.com/java9/java9-pStreet-interface-methods
valijon

13

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

  1. डिफ़ॉल्ट तरीकों ने इंटरफ़ेस के क्लासिक पैटर्न और एक साथी वर्ग का अंत कर दिया है जो उस इंटरफ़ेस में अधिकांश या सभी तरीकों को लागू करता है। एक उदाहरण है Collection and AbstractCollection। अब हमें डिफ़ॉल्ट कार्यक्षमता प्रदान करने के लिए इंटरफ़ेस में विधियों को लागू करना चाहिए। जो कक्षाएं इंटरफ़ेस को लागू करती हैं, उनके पास तरीकों को ओवरराइड करने या डिफ़ॉल्ट कार्यान्वयन को चुनने का विकल्प होता है।
  2. डिफ़ॉल्ट विधियों का एक और महत्वपूर्ण उपयोग है interface evolution। मान लीजिए कि मेरे पास एक क्लास बॉल थी:

    public class Ball implements Collection { ... }

अब Java 8 में एक नया फीचर पेश किया गया है। streamइंटरफ़ेस में जोड़े गए विधि का उपयोग करके हम एक स्ट्रीम प्राप्त कर सकते हैं । यदि streamडिफ़ॉल्ट विधि नहीं Collectionहोती तो इंटरफ़ेस के लिए सभी कार्यान्वयन टूट जाते क्योंकि वे इस नई पद्धति को लागू नहीं कर रहे होते। एक इंटरफ़ेस में एक गैर-डिफ़ॉल्ट विधि जोड़ना नहीं है source-compatible

लेकिन मान लीजिए कि हम कक्षा को फिर से नहीं जोड़ते हैं और एक पुरानी जार फ़ाइल का उपयोग करते हैं जिसमें यह वर्ग होता है Ball। इस लापता पद्धति के बिना कक्षा ठीक-ठाक लोड हो जाएगी, उदाहरण बन सकते हैं और ऐसा लगता है कि सब कुछ ठीक काम कर रहा है। लेकिन अगर कार्यक्रम हम streamउदाहरण के लिए आमंत्रित करता है, तो Ballहमें मिलेगा AbstractMethodError। इसलिए विधि डिफ़ॉल्ट बनाने से दोनों समस्याओं का हल हो गया।


9

जावा इंटरफेस में डिफ़ॉल्ट तरीके इंटरफ़ेस विकास को सक्षम करते हैं

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

एक स्थिर विधि एक वर्ग के लिए अद्वितीय है। एक डिफ़ॉल्ट विधि वर्ग के उदाहरण के लिए अद्वितीय है।

यदि आप किसी मौजूदा इंटरफ़ेस में एक डिफ़ॉल्ट विधि जोड़ते हैं, तो इस इंटरफ़ेस को लागू करने वाले वर्ग और इंटरफ़ेस को इसे लागू करने की आवश्यकता नहीं है। वे कर सकते हैं

  • डिफ़ॉल्ट विधि को लागू करें, और यह कार्यान्वित इंटरफ़ेस में कार्यान्वयन को ओवरराइड करता है।
  • विधि (कार्यान्वयन के बिना) को फिर से घोषित करें जो इसे अमूर्त बनाता है।
  • कुछ भी न करें (तब लागू इंटरफ़ेस से डिफ़ॉल्ट विधि विरासत में मिली है)।

विषय पर अधिक यहाँ


7

हालांकि इसका एक पुराना सवाल है कि मैं इस पर अपना इनपुट दूं।

  1. अमूर्त वर्ग: अमूर्त वर्ग के अंदर हम उदाहरण चर घोषित कर सकते हैं, जो बाल वर्ग के लिए आवश्यक हैं

    इंटरफ़ेस: इंटरफ़ेस के अंदर हर चर हमेशा सार्वजनिक स्थिर होता है और अंतिम रूप से हम उदाहरण चर घोषित नहीं कर सकते

  2. अमूर्त वर्ग: सार वर्ग वस्तु की स्थिति के बारे में बात कर सकता है

    इंटरफ़ेस: इंटरफ़ेस कभी भी वस्तु की स्थिति के बारे में बात नहीं कर सकता है

  3. अमूर्त वर्ग: अंदर का सार वर्ग हम कंस्ट्रक्टरों की घोषणा कर सकते हैं

    इंटरफ़ेस: इंटरफ़ेस के अंदर हम कंस्ट्रक्टरों को घोषित नहीं कर सकते क्योंकि कंस्ट्रक्टर्स का उद्देश्य
    उदाहरण चर को शुरू करना है। तो अगर वहाँ हम इंटरफेस में उदाहरण चर नहीं हो सकता है तो निर्माणकर्ता की क्या आवश्यकता है

  4. अमूर्त वर्ग: अमूर्त वर्ग के अंदर हम उदाहरण और स्थिर ब्लॉक की घोषणा कर सकते हैं

    इंटरफ़ेस: इंटरफेस में उदाहरण और स्थिर ब्लॉक नहीं हो सकते।

  5. सार वर्ग: सार वर्ग लंबोदर अभिव्यक्ति का संदर्भ नहीं दे सकता है

    इंटरफेस: एकल सार पद्धति के साथ इंटरफेस लैम्ब्डा अभिव्यक्ति का उल्लेख कर सकते हैं

  6. अमूर्त वर्ग : अमूर्त वर्ग के अंदर हम OBJECT CLASS विधियों को ओवरराइड कर सकते हैं

    इंटरफेस: हम इंटरफेस के अंदर OBJECT CLASS मेथड को ओवरराइड नहीं कर सकते।

मैं नोट पर समाप्त करूंगा कि:

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


5

रेमी फॉरेक्स नियम आप सार वर्गों के साथ डिजाइन नहीं है। आप अपने ऐप को इंटरफेस के साथ डिज़ाइन करें । Watever जावा का संस्करण है, जो भी भाषा है। यह SOL I D सिद्धांतों में I nterface पृथक्करण सिद्धांत द्वारा समर्थित है ।

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


2

डिफ़ॉल्ट तरीकों के साथ इंटरफ़ेस का उपयोग कब किया जाना चाहिए और एक सार वर्ग का उपयोग कब किया जाना चाहिए?

पिछड़ी संगतता: कल्पना करें कि आपका इंटरफ़ेस सैकड़ों वर्गों द्वारा कार्यान्वित किया गया है, उस इंटरफ़ेस को संशोधित करके सभी उपयोगकर्ताओं को नए जोड़े गए तरीके को लागू करने के लिए मजबूर किया जाएगा, भले ही यह कई अन्य वर्गों के लिए आवश्यक नहीं हो सकता है जो आपके इंटरफ़ेस को लागू करता है, साथ ही यह आपके इंटरफ़ेस की अनुमति देता है एक कार्यात्मक इंटरफ़ेस होने के लिए

तथ्य और प्रतिबंध:

1-मई केवल एक अंतरफलक के भीतर घोषित किया जाना चाहिए और एक वर्ग या अमूर्त वर्ग के भीतर नहीं।

2-एक शरीर प्रदान करना चाहिए

3-यह एक इंटरफ़ेस में उपयोग किए जाने वाले अन्य सामान्य तरीकों की तरह अमूर्त नहीं माना जाता है।


1

जावा 8 में, एक इंटरफ़ेस एक सार वर्ग की तरह दिखता है, हालांकि उनके कुछ अंतर हो सकते हैं जैसे:

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

2) डिफ़ॉल्ट तरीकों और सार वर्ग के साथ इंटरफेस के बीच एक और अंतर यह है कि आप कंस्ट्रक्टरों को एक सार वर्ग के अंदर परिभाषित कर सकते हैं , लेकिन आप जावा में इंटरफ़ेस के अंदर कंस्ट्रक्टर को परिभाषित नहीं कर सकते हैं।


मैं # 2 से सहमत हूं, लेकिन # 1 के लिए, क्या आप केवल इंटरफ़ेस लागू नहीं कर सकते हैं और इस प्रकार कार्यान्वयन कक्षा के माध्यम से एक स्थिति है?
जॉर्ज जेवियर

0

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

अमूर्त कक्षा की विधियाँ हालांकि एक सार्थक कार्यान्वयन देने वाली हैं, जो कि किसी भी बच्चे की कक्षा को सामान्य कार्यक्षमता को ओवरराइड करने के लिए आवश्यक होने पर ही ओवरराइड करना चाहिए।


0

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

अन्यथा, यदि आप किसी इंटरफ़ेस में कार्यान्वयन जोड़ते हैं , तो आप मौलिक कानून को तोड़ रहे हैं, क्योंकि पहले स्थान पर इंटरफेस क्यों जोड़े गए थे। जावा, C + के विपरीत एक एकल वंशानुक्रम भाषा है, जो एकाधिक वंशानुक्रम के लिए अनुमति देता है। Interfaces टाइपिंग के लाभ प्रदान करते हैं जो एक ऐसी भाषा के साथ आते हैं जो एकाधिक वंशानुक्रम के साथ आने वाली समस्याओं का परिचय दिए बिना एकाधिक वंशानुक्रम का समर्थन करती है।

विशेष रूप से, जावा केवल कार्यान्वयन के एकल वंशानुक्रम की अनुमति देता है, लेकिन यह इंटरफेस के कई वंशानुक्रम की अनुमति देता है। उदाहरण के लिए, निम्न मान्य जावा कोड है:

class MyObject extends String implements Runnable, Comparable { ... }

MyObject केवल एक कार्यान्वयन विरासत में मिला है, लेकिन यह तीन अनुबंधों को विरासत में मिला है।

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

मेरी बात का समर्थन करने के लिए, केन अर्नोल्ड और जेम्स गोस्लिंग की पुस्तक द जावा प्रोग्रामिंग लैंग्वेज, 4 संस्करण से एक उद्धरण दिया गया है :

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


-1

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

अपने आप से कुछ सवाल पूछें: आप अपने तरीकों को अमूर्त वर्ग में क्यों नहीं डाल सकते हैं? क्या आपको एक से अधिक अमूर्त वर्ग की आवश्यकता होगी? फिर सोचें कि आपकी कक्षा किसके लिए जिम्मेदार है। क्या आप सुनिश्चित हैं कि सभी विधियाँ जो आप एकल वर्ग में डालने जा रही हैं, वास्तव में उसी उद्देश्य को पूरा करेंगी? हो सकता है कि आप कई उद्देश्यों में अंतर करेंगे और फिर अपनी कक्षा को कई वर्गों में विभाजित करेंगे, प्रत्येक उद्देश्य के लिए अपनी कक्षा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.