जावा में विभिन्न रिटर्न प्रकार के साथ अधिभार?


104

केवल रिटर्न प्रकार को बदलकर किसी फ़ंक्शन को अधिभार देना क्यों संभव नहीं है? क्या यह जावा के भविष्य के संस्करण में बदल जाएगा?

वैसे, केवल संदर्भ के लिए, क्या यह C ++ में संभव है?



KNU, ​​अन्य उत्तर इस मायने में भिन्न है कि यह सामान्य, गैर-भाषा विशिष्ट शब्दों में प्रश्न पूछता है। यह भी दिलचस्प है कि अन्य प्रश्न का स्वीकृत उत्तर यह निर्दिष्ट करके आगे बढ़ता है कि जावा जेवीएम इसे इंटर्नल के हेरफेर के साथ करने की अनुमति देता है।
J Woodchuck

जवाबों:


157

आप इसे जावा में नहीं कर सकते, और आप इसे C ++ में नहीं कर सकते। तर्क यह है कि संकलक के लिए अकेले वापसी मूल्य पर्याप्त नहीं है कि किस फ़ंक्शन को कॉल किया जाए:

public int foo() {...}
public float foo() {..}

...
foo(); // which one?

3
मैं हमेशा सोचता था कि अगर हमने int i = foo () या float f = foo () जैसा कुछ किया है तो यह पता चलेगा कि कौन सा है, लेकिन यदि कथन सिर्फ फ़ंक्शन है कि यह संकलक को पता नहीं होगा। मुझे पता है। धन्यवाद।
ननोस

7
@nunos भले ही यह फ्लोट f = foo () हो, कंपाइलर इसका पता लगाने में सक्षम नहीं होगा, क्योंकि दोनों एक int एक फ्लोट के लिए वैध इनपुट होंगे। फ्लोट एफ = 7 की तुलना करें; (7 एक फ्लोट या इंट?)
नोमेन

5
@NomeN लेकिन आपका कथन बताता है कि फंक (int i) और func (float i) संकलक के लिए अविभाज्य होगा - और हम सभी जानते हैं कि यह सच नहीं है। असली कारण ओयड द्वारा दिया गया है (अगला उत्तर देखें) - यह विधि के हस्ताक्षर के बारे में है। और, बी.टी.वी. 7 निश्चित रूप से पूर्णांक है, जबकि 7.0 या 7 एफ फ्लोट है ;-)
टा सास

7
7.0 नहीं है float, यह नहीं है double
fredoverflow

3
तथ्य यह है कि foo();वापसी प्रकार के बिना अस्पष्ट होगा जरूरी नहीं कि इसे एक अधिभार के रूप में अस्वीकार कर दिया जाए। ऐसे तर्क हैं जो अस्पष्टता (जैसे foo(null);) का कारण बन सकते हैं , लेकिन यह अधिभार को स्वाभाविक रूप से अमान्य नहीं बनाता है।
shmosel

48

कारण यह है कि जावा में ओवरलोड केवल विभिन्न हस्ताक्षर वाले तरीकों के लिए अनुमत हैं ।

वापसी प्रकार विधि हस्ताक्षर का हिस्सा नहीं है, इसलिए इसका उपयोग ओवरलोड को अलग करने के लिए नहीं किया जा सकता है।

जावा ट्यूटोरियल से परिभाषित करने के तरीके देखें ।


4
लेकिन वापसी प्रकार हस्ताक्षर
-१४

51
ओह "सिर्फ इसलिए"! समझा।
औरो

3
वापसी प्रकार IS विधि हस्ताक्षर का एक हिस्सा है। बस क्लास डिसाइडफ़ॉर्म में देखें।
कोनमिक

2
यह वास्तव में @konmik नहीं है - विधि अधिभार के नियमों द्वारा नहीं। कोशिश करो। एक ही विधि का नाम, एक ही क्रम में एक ही पैरामीटर प्रकार, विभिन्न वापसी प्रकार। संकलन नहीं होगा।
ऊद

3
हां, क्योंकि रिटर्न प्रकार हस्ताक्षर का हिस्सा नहीं है । हस्ताक्षर है - विधि का नाम + इसके पैरामीटर के प्रकार और क्रम। मेरे उत्तर में दिए गए लिंक को पढ़ें: "ऊपर घोषित विधि का हस्ताक्षर है: calculateAnswer(double, int, double, double)"। देखें कि रिटर्न प्रकार शामिल नहीं है, @konmik।
ऊद

22

जावा 5.0 से पहले, जब आप एक विधि को ओवरराइड करते हैं, तो दोनों पैरामीटर और रिटर्न प्रकार बिल्कुल मेल खाना चाहिए। जावा 5.0 में, यह एक नई सुविधा का परिचय देता है जिसे सहसंयोजक वापसी प्रकार कहा जाता है। आप एक ही हस्ताक्षर के साथ एक विधि को ओवरराइड कर सकते हैं लेकिन लौटाए गए ऑब्जेक्ट का उपवर्ग लौटाते हैं। दूसरे शब्दों में, एक उपवर्ग में एक विधि एक वस्तु को लौटा सकती है जिसका प्रकार सुपरक्लास में उसी हस्ताक्षर के साथ विधि द्वारा लौटाए गए प्रकार का उपवर्ग है।


3
जब मैंने पहली बार यह देखा तो मैं चकरा गया था। यह समझाने के लिए धन्यवाद कि यह क्यों संभव है!
डायलन नोल्स

2
ओवरलोडिंग और ओवरराइडिंग अलग हैं। ओवरलोडिंग (आवश्यक रूप से) वंशानुक्रम में शामिल नहीं है
इंदिवुइया

3
यह उत्तर जावा में एक नौसिखिया के लिए भ्रामक लग सकता है, क्योंकि यह ओवरलोडिंग के साथ बिल्कुल भी प्रासंगिक नहीं है , यह ओवरराइडिंग है - पूरी तरह से हर चीज।
azizbekian

4

Overloaded जावा में तरीकों के अलग-अलग रिटर्न प्रकार हो सकते हैं जो कि तर्क भी अलग हैं।

सैंपल कोड देखें।

public class B {

    public String greet() {
        return "Hello";
    }

    //This will work
    public StringBuilder greet(String name) {
        return new StringBuilder("Hello " + name);
    }

    //This will not work
    //Error: Duplicate method greet() in type B
    public StringBuilder greet() {
        return new StringBuilder("Hello Tarzan");
    }

}

मूल रूप से रिटर्न प्रकार को ध्यान में नहीं रखा गया है, केवल तर्क, दुखद लेकिन सच है
अलेक्जेंडर मिल्स

1

कंपाइलर रिटर्न प्रकार पर विचार नहीं करता है जब अलग-अलग तरीके, इसलिए आप एक ही हस्ताक्षर के साथ दो तरीकों की घोषणा नहीं कर सकते हैं भले ही उनके पास एक अलग रिटर्न प्रकार हो।


1

किसी विधि को ओवरलोड करते समय रिटर्न प्रकार मायने नहीं रखता है। हमें केवल यह सुनिश्चित करने की आवश्यकता है कि कोई अस्पष्टता नहीं है!

एकमात्र तरीका जावा को पता चल सकता है कि कॉल करने की कौन सी विधि तर्क सूची के प्रकारों को अलग करती है। यदि कंपाइलर एक ही नाम और एक ही प्रकार के तर्क के साथ दो तरीकों की अनुमति देता है, तो यह निर्धारित करने का कोई तरीका नहीं होगा कि उसे किसको कॉल करना चाहिए।


0

कंपाइलर रिटर्न प्रकार पर विचार नहीं करता है जब अलग-अलग तरीके, इसलिए आप एक ही हस्ताक्षर के साथ दो तरीकों की घोषणा नहीं कर सकते हैं भले ही उनके पास एक अलग रिटर्न प्रकार हो।

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

Compile Time Error Run Time Error से बेहतर है। यदि आप समान पैरामीटर वाले समान विधि की घोषणा करते हैं, तो जावा कंपाइलर कंपाइलर टाइम एरर को रेंडर करता है।


यह स्वीकृत उत्तर से कैसे भिन्न है? (यह भी कारण है कि यह एक संकलन समय त्रुटि है क्योंकि संकलक यह पता लगाने के लिए कि किस विधि को कॉल नहीं कर सकता है, इसलिए यह उचित निष्पादन योग्य कोड उत्पन्न करने के लिए कैसे माना जाता है)
अनहोनीशीप

-2

नहीं वास्तव में संभव नहीं है कि जिस तरह से आप केवल तर्कों या डेटा प्रकार के तर्कों के द्वारा अधिभार कर सकते हैं

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