जावा इंटरफेस में वैकल्पिक तरीके


120

मेरी समझ से यदि आप जावा में एक इंटरफ़ेस लागू करते हैं, तो उस इंटरफ़ेस में निर्दिष्ट विधियों का उपयोग उप-वर्गों द्वारा उक्त इंटरफ़ेस को लागू करने के लिए किया जाना है।

मैंने देखा है कि कुछ इंटरफ़ेस जैसे कि संग्रह इंटरफ़ेस में ऐसी विधियाँ हैं जो वैकल्पिक रूप से टिप्पणी की जाती हैं, लेकिन वास्तव में इसका क्या मतलब है? इसका मुझे थोड़ा फेंक दिया गया क्योंकि मुझे लगा कि इंटरफ़ेस में निर्दिष्ट सभी तरीकों की आवश्यकता होगी?


आप किन तरीकों का जिक्र कर रहे हैं? मैं इसे JavaDoc या स्रोत कोड
dcpomero


जवाबों:


232

लगता है यहाँ के जवाबों में एक बहुत बड़ी उलझन है।

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

यह समझना महत्वपूर्ण है कि इंटरफ़ेस के अनुरूप दो स्तर होते हैं:

  1. जावा भाषा क्या जांच सकती है। यह बहुत ज्यादा सिर्फ उबलता है: क्या प्रत्येक विधियों के लिए कुछ कार्यान्वयन है?

  2. वास्तव में अनुबंध को पूरा करना। यही है, क्या कार्यान्वयन वह करता है जो इंटरफ़ेस में दस्तावेज़ीकरण कहता है कि उसे क्या करना चाहिए?

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

कलेक्शंस एपीआई को डिजाइन करते समय यहोशू बलोच ने फैसला किया कि संग्रह के विभिन्न प्रकारों के बीच अंतर करने के लिए बहुत बारीक-बारीक इंटरफेस होने के बजाय (जैसे: पठनीय, लिखने योग्य, यादृच्छिक-पहुंच आदि) वह केवल इंटरफेस के बहुत मोटे सेट होंगे। Collection, List, Setऔर Map, और उसके बाद के रूप में "वैकल्पिक" निश्चित संचालनों के दस्तावेज़। यह दहनशील विस्फोट से बचने के लिए था जो ठीक दाने वाले इंटरफेस से उत्पन्न होगा। से जावा संग्रह एपीआई डिजाइन पूछे जाने वाले प्रश्न :

समस्या को गोर विस्तार से समझाने के लिए, मान लीजिए कि आप पदानुक्रम में परिवर्तनशीलता की धारणा जोड़ना चाहते हैं। आपको चार नए इंटरफ़ेस चाहिए: ModifiableCollection, ModifiableSet, ModifiableList और ModifiableMap। जो पहले एक साधारण पदानुक्रम था वह अब एक गन्दा पदानुक्रम है। इसके अलावा, आपको unmodifiable संग्रह के साथ उपयोग के लिए एक नया Iterator इंटरफ़ेस की आवश्यकता है, जिसमें निकालें ऑपरेशन शामिल नहीं है। अब आप UnsupportedOperationException के साथ दूर कर सकते हैं? दुर्भाग्य से नहीं।

सरणियों पर विचार करें। वे सूची के अधिकांश कार्यों को कार्यान्वित करते हैं, लेकिन हटाते और जोड़ते नहीं हैं। वे "निश्चित आकार" सूची हैं। यदि आप पदानुक्रम में इस धारणा को कैप्चर करना चाहते हैं, तो आपको दो नए इंटरफ़ेस जोड़ने होंगे: VariableSizeList और VariableSizeMap। आपको VariableSizeCollection और VariableSizeSet ​​को जोड़ने की आवश्यकता नहीं है, क्योंकि वे ModifiableCollection और ModifiableSet के समान होंगे, लेकिन आप उन्हें संगति के लिए वैसे भी जोड़ना चुन सकते हैं। इसके अलावा, आपको एक नई किस्म की लिस्टइंटरेटर की आवश्यकता होती है, जो अनमॉडिबल लिस्ट के साथ जाने के लिए ऐड और ऑपरेशन को सपोर्ट न करे। अब हम अपने मूल चार के बजाय दस या बारह इंटरफेस, प्लस दो नए इटरेटर इंटरफेस तक हैं। हम कर रहे हैं? नहीं।

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

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

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

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

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

ध्यान दें कि क्योंकि UnsupportedOperationExceptionएक RuntimeExceptionतो आप इसे किसी भी तरीके से कार्यान्वयन से, जहाँ तक संकलक का संबंध है फेंक कर सकते हैं। उदाहरण के लिए, आप इसे कार्यान्वयन से फेंक सकते हैं Collection.size()। हालांकि, इस तरह के कार्यान्वयन अनुबंध का उल्लंघन करेंगे क्योंकि प्रलेखन Collection.size()यह नहीं कहता है कि यह अनुमति है।

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


30
के लिए +1 There are no exceptions to this rule। आश्चर्य है कि इस उत्तर को क्यों स्वीकार नहीं किया गया है। अन्य अच्छे हैं लेकिन आपने पर्याप्त से अधिक दिया है।
xyz

9
"जावा भाषा के लिए यह आवश्यक है कि एक इंटरफ़ेस में प्रत्येक विधि उस इंटरफ़ेस के प्रत्येक कार्यान्वयन द्वारा कार्यान्वित की जाए। अवधि। इस नियम के कोई अपवाद नहीं हैं।" सिवाय ... जब वहाँ हैं। :-) जावा 8 इंटरफेस एक डिफ़ॉल्ट विधि कार्यान्वयन को निर्दिष्ट कर सकता है, इस प्रकार, जावा 8 में ... यह सच नहीं है कि इंटरफ़ेस में प्रत्येक विधि को इंटरफ़ेस के प्रत्येक कार्यान्वयन के लिए आवश्यक होना चाहिए, कम से कम इस अर्थ में नहीं कि आपको चाहिए कोन्रेक्ट क्लास में कार्यान्वयन कोड।
डब्लिक

1
@DaBlick जब मैंने कहा "हर कार्यान्वयन द्वारा कार्यान्वित किया जाता है" मेरा मतलब यह नहीं था कि कहा गया है कि कार्यान्वयन को लागू करने वाले वर्ग के स्रोत में रहना चाहिए। यहां तक ​​कि जावा 8 से पहले, एक इंटरफ़ेस विधि के कार्यान्वयन को विरासत में ले सकता है, यहां तक ​​कि उस वर्ग से भी जो इंटरफ़ेस को लागू नहीं करता है। उदाहरण: बनाएँ Fooकि Runnableसार्वजनिक विधि के साथ लागू नहीं होता है void run()। अब एक वर्ग बनाने Barकि extends Fooऔर implements Runnableoveriding बिना run। यह अभी भी विधि को लागू करता है, यद्यपि अप्रत्यक्ष रूप से। इसी तरह, एक डिफ़ॉल्ट विधि कार्यान्वयन अभी भी एक कार्यान्वयन है।
लारेंस गोंसाल्वेस

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

3
@AndrewS क्योंकि जावा 8 removeमें एक डिफ़ॉल्ट कार्यान्वयन दिया गया था। यदि आप इसे लागू नहीं करते हैं, तो आपकी कक्षा को डिफ़ॉल्ट कार्यान्वयन मिलता है। आपके द्वारा उल्लिखित अन्य दो विधियों में डिफ़ॉल्ट कार्यान्वयन नहीं है।
लॉरेंस गोंसाल्वेस

27

एक इंटरफ़ेस के लिए एक कार्यान्वयन (गैर सार) वर्ग को संकलित करने के लिए - सभी तरीकों को लागू किया जाना चाहिए।

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

संग्रह में "वैकल्पिक" का अर्थ है कि कार्यान्वयन वर्ग को 'कार्यान्वयन' नहीं करना है (ऊपर की शब्दावली के अनुसार) इसे, और इसे बस फेंक दिया जाएगा NotSupportedException)।

एक अच्छा उदाहरण- add()अपरिवर्तनीय संग्रह के लिए विधि - कंक्रीट बस एक ऐसी विधि को लागू करेगी जो फेंकने के अलावा कुछ भी नहीं करती हैNotSupportedException

के मामले में Collectionयह गंदे विरासत पेड़ों को रोकने के लिए किया जाता है, जो प्रोग्रामर को दुखी कर देगा - लेकिन ज्यादातर मामलों के लिए, इस प्रतिमान की सलाह नहीं दी जाती है, और यदि संभव हो तो इसे टाला जाना चाहिए।


अपडेट करें:

जावा 8 के रूप में, एक डिफ़ॉल्ट विधि पेश की गई थी।

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

ध्यान दें कि विधि अभी भी सभी वर्गों द्वारा लागू की जाती है जो इसे घोषित करते हैं, लेकिन इंटरफ़ेस की परिभाषा का उपयोग करते हुए।


"नहीं गड़बड़ कर रहा है" के बजाय, मुझे लगता है कि यह "यह बस ऐसा ही है" यह अधिक है।

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

12
"इसे लागू करने की आवश्यकता नहीं है (यह संभवतः एक विधि बना देगा जो फेंकता है ...)"। यही कारण है कि है विधि को लागू करने।
लोर्ने का मार्कीट

1
जैसा कि यह दुर्भाग्य से स्वीकृत उत्तर है, मैं इसे फिर से लिखने का सुझाव दूंगा। ' आमतौर पर , सभी वर्गों को लागू करना चाहिए (और होगा) को लागू करना' भ्रामक है क्योंकि ईजेपी पहले से ही बताया गया है।
अल्बर्टो

2
संग्रह में "वैकल्पिक" का मतलब है कि कार्यान्वयन वर्ग को इसे लागू करने की आवश्यकता नहीं है। "- यह स्पष्ट रूप से गलत है।" द्वारा "आपको" लागू करने की आवश्यकता नहीं है "इसका मतलब कुछ और है।
djechlin

19

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

interface Foo {
  void doSomething();
  void doSomethingElse();
}

class MyClass implements Foo {
  public void doSomething() {
     /* All of my code goes here */
  }

  public void doSomethingElse() {
    // I leave this unimplemented
  }
}

अब मैंने इसे छोड़ दिया है doSomethingElse(), इसे लागू करने के लिए अपने उपवर्गों को छोड़ दिया है। यह वैकल्पिक है।

class SubClass extends MyClass {
    @Override
    public void doSomethingElse() {
      // Here's my implementation. 
    }
}

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


मैं तुम मेरे दोस्त को चूम सकता है।
माइक्रो

16

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

कुछ संग्रह कार्यान्वयन में उन तत्वों पर प्रतिबंध है जो उनके पास हो सकते हैं। उदाहरण के लिए, कुछ कार्यान्वयन अशक्त तत्वों को प्रतिबंधित करते हैं, और कुछ को उनके तत्वों के प्रकारों पर प्रतिबंध है। अयोग्य तत्व को जोड़ने का प्रयास एक अनियंत्रित अपवाद को फेंक देता है, आमतौर पर NullPointerException या ClassContException। एक अयोग्य तत्व की उपस्थिति को क्वेरी करने का प्रयास एक अपवाद फेंक सकता है, या यह केवल गलत वापस कर सकता है; कुछ कार्यान्वयन पूर्व व्यवहार का प्रदर्शन करेंगे और कुछ बाद का प्रदर्शन करेंगे। अधिक आम तौर पर, एक अयोग्य तत्व पर एक ऑपरेशन का प्रयास करना, जिसके पूरा होने पर संग्रह में एक अयोग्य तत्व के सम्मिलन का परिणाम नहीं होगा या कार्यान्वयन के विकल्प पर सफल हो सकता है। ऐसे अपवादों को "वैकल्पिक" के रूप में चिह्नित किया जाता है


मुझे वास्तव में कभी समझ में नहीं आया कि वैकल्पिक द्वारा javadocs का क्या मतलब है। मेरा मानना ​​है कि जैसा आपने कहा, उनका मतलब है। लेकिन अधिकांश विधियाँ उस मानक द्वारा वैकल्पिक हैं new Runnable ( ) { @ Override public void run ( ) { throw new UnsupportedOperationException ( ) ; } }:;
एमोरी

यह वैकल्पिक तरीकों पर लागू नहीं होता है , बल्कि यह कि, उदाहरण के लिए, add((T)null)एक मामले में मान्य हो सकता है लेकिन दूसरा नहीं । यही है, यह वैकल्पिक अपवादों / व्यवहार और तर्कों ("तत्वों पर प्रतिबंध" ... "अयोग्य तत्व" ... "अपवादों को वैकल्पिक" के रूप में चिह्नित करता है) और वैकल्पिक तरीकों को संबोधित नहीं करता है ।

9

सभी तरीकों को कोड को संकलित करने के लिए लागू किया जाना है, ( defaultजावा 8+ में कार्यान्वयन के साथ उन लोगों से अलग ), लेकिन कार्यान्वयन को कार्यात्मक रूप से उपयोगी कुछ भी नहीं करना है। विशेष रूप से, यह:

  • खाली (खाली तरीका) हो सकता है।
  • बस UnsupportedOperationException(या समान) फेंक सकते हैं

बाद के दृष्टिकोण को अक्सर संग्रह कक्षाओं में लिया जाता है - सभी विधियों को अभी भी लागू किया जाता है, लेकिन कुछ को अपवाद कहा जा सकता है यदि रनटाइम पर बुलाया जाता है।


5

वास्तव में, मैं SurfaceView.Callback2 से प्रेरित हूं। मुझे लगता है कि यह आधिकारिक तरीका है

public class Foo {
    public interface Callback {
        public void requiredMethod1();
        public void requiredMethod2();
    }

    public interface CallbackExtended extends Callback {
        public void optionalMethod1();
        public void optionalMethod2();
    }

    private Callback mCallback;
}

यदि आपके वर्ग को वैकल्पिक तरीकों को लागू करने की आवश्यकता नहीं है, तो बस "कॉलबैक लागू करता है"। यदि आपकी कक्षा को वैकल्पिक तरीकों को लागू करने की आवश्यकता है, तो बस "कॉलबैकटेक्स्टेड लागू करें"।

अंग्रेजी के लिए क्षमा करें।


5

जावा 8 और बाद में, इस प्रश्न का उत्तर अभी भी मान्य है, लेकिन अब अधिक बारीक है।

पहले, स्वीकृत उत्तर के ये कथन सही हैं:

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

तो, जावा 8 में नया क्या है? जब की बात "वैकल्पिक तरीके" निम्न में से कोई अब उपयुक्त हैं:

1. एक विधि जिसका कार्यान्वयन संविदात्मक वैकल्पिक है

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

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

public SomeReturnType optionalInterfaceMethodA(...) {
    throw new UnsupportedOperationException();
}

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

2. एक डिफ़ॉल्ट विधि जिसका पुन: कार्यान्वयन वैकल्पिक है

जावा 8 ने डिफ़ॉल्ट विधियों की अवधारणा पेश की । ये ऐसी विधियाँ हैं जिनके कार्यान्वयन को इंटरफ़ेस परिभाषा द्वारा ही प्रदान किया जा सकता है और प्रदान किया जाता है। यह आम तौर पर केवल डिफ़ॉल्ट तरीके प्रदान करना संभव है जब विधि निकाय को अन्य इंटरफ़ेस विधियों (अर्थात, "आदिम") का उपयोग करके लिखा जा सकता है, और जब thisइसका अर्थ "यह हो सकता है कि किस वर्ग ने इस इंटरफ़ेस को लागू किया है।"

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

इस नए परिवेश में, जावा कलेक्शंस फ्रेमवर्क को फिर से लिखा जा सकता है :

public interface List<E> {
    :
    :
    default public boolean add(E element) {
        throw new UnsupportedOperationException();
    }
    :
    :
}

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

इस मामले में, ऊपर दिया गया "तीसरा कथन" अभी भी सही है, क्योंकि विधि को इंटरफ़ेस में ही लागू किया गया है।

3. एक विधि जो एक Optionalपरिणाम लौटाती है

अंतिम नई तरह की वैकल्पिक विधि बस एक विधि है जो एक रिटर्न देती है OptionalOptionalवर्ग से निपटने का एक निश्चित अधिक वस्तु उन्मुख तरीका प्रदान करता है nullका परिणाम है।

प्रोग्रामिंग की धाराप्रवाह शैली में, जैसे कि आमतौर पर नए जावा स्ट्रीम एपीआई के साथ कोडिंग करते समय किसी भी बिंदु पर एक अशक्त परिणाम प्रोग्राम को NullPointerException के साथ क्रैश करने का कारण बनता है। Optionalवर्ग एक तरीका है कि दुर्घटना के लिए ग्राहक कोड पैदा करने के बिना धाराप्रवाह शैली में सक्षम बनाता है में क्लाइंट कोड को अशक्त परिणाम देने के लिए एक तंत्र प्रदान करता है।


4

अगर हम grepCode में AbstractCollection.java के कोड के माध्यम से जाते हैं जो सभी संग्रह कार्यान्वयन के लिए एक पूर्वज वर्ग है, तो यह हमें वैकल्पिक तरीकों के अर्थ को समझने में मदद करेगा। यहां AbstractCollection class में add (e) मेथड के लिए कोड दिया गया है। संग्रह इंटरफ़ेस के अनुसार add (e) विधि वैकल्पिक है

public boolean  add(E e) {

        throw new UnsupportedOperationException();
    } 

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


4

खैर, इस विषय को स्वीकार किया गया है ... हाँ .. लेकिन सोचिए, एक जवाब गायब है। Im इंटरफेस के "डिफ़ॉल्ट तरीके" के बारे में बात कर रहा है। उदाहरण के लिए, आइए कल्पना करें कि आपके पास कुछ भी बंद करने के लिए एक वर्ग होगा (जैसे विध्वंसक या कुछ और)। मान लीजिए कि इसके 3 तरीके होने चाहिए। चलो उन्हें "doFirst ()", "doLast ()" और "onClose ()" कहते हैं।

तो हम कहते हैं कि हम उस प्रकार की किसी भी वस्तु को कम से कम "onClose ()" का एहसास कराना चाहते हैं, लेकिन दूसरे वैकल्पिक हैं।

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

तो अगर आप इसे इस तरह से महसूस करना चाहते हैं, तो यह निम्नलिखित होगा

public interface Closer {
    default void doFirst() {
        System.out.print("first ... ");
    }
    void onClose();
    default void doLast() {
        System.out.println("and finally!");
    }
}

अब क्या होगा, यदि आप उदाहरण के लिए इसे "टेस्ट" नामक कक्षा में लागू करते हैं, तो संकलक निम्नलिखित के साथ बिल्कुल ठीक होगा:

public class TestCloser implements Closer {
    @Override
    public void onClose() {
        System.out.print("closing ... ");
    }
}

आउटपुट के साथ:

first ... closing ... and finally!

या

public class TestCloser implements Closer {
    @Override
    public void onClose() {
        System.out.print("closing ... ");
    }

    @Override
    public void doLast() {
        System.out.println("done!");
    }
}

आउटपुट के साथ:

first ... closing ... done!

सभी संयोजन संभव हैं। "डिफ़ॉल्ट" के साथ कुछ भी लागू किया जा सकता है, लेकिन लागू होने के बिना कुछ भी नहीं करना चाहिए।

आशा है कि यह पूरी तरह से गलत नहीं है कि मैं अब जवाब देता हूं।

आपका दिन मंगलमय हो!

[edit1]: कृपया ध्यान दें: यह केवल जावा Please में काम करता है।


हाँ, क्षमा करें, मैं यह उल्लेख करना भूल गया ... अब संपादित किया जाना चाहिए।
थोरबेन कुक

1

मैं कॉल बैक इंटरफ़ेस को लागू करने का एक तरीका ढूंढ रहा था, इसलिए वैकल्पिक तरीकों को लागू करना आवश्यक था क्योंकि मैं प्रत्येक कॉल बैक के लिए प्रत्येक विधि को लागू नहीं करना चाहता था।

इसलिए, मैंने एक इंटरफ़ेस का उपयोग करने के बजाय, खाली क्रियान्वयन के साथ एक वर्ग का उपयोग किया जैसे:

public class MyCallBack{
    public void didResponseCameBack(String response){}
}

और आप सदस्य चर कॉलबैक को इस तरह सेट कर सकते हैं,

c.setCallBack(new MyCallBack() {
    public void didResponseCameBack(String response) {
        //your implementation here
    }
});

तो इसे इस तरह से कॉल करें।

if(mMyCallBack != null) {
    mMyCallBack.didResponseCameBack(response);
}

इस तरह, आपको प्रति कॉल वापस आने के लिए हर तरीके को लागू करने के बारे में चिंता करने की ज़रूरत नहीं है, लेकिन केवल उन लोगों को ओवरराइड करें जिनकी आपको ज़रूरत है।


0

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


0

ओरेकल के जावा कलेक्शंस ट्यूटोरियल:

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

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