2011-01-07 7 views
9

मैं जावा प्रशिक्षण पुस्तिका पढ़ रहा था और यह कहा कि जावा में विधि ओवरलोडिंग एक अलग तर्क सूची के द्वारा हासिल की जा सकती है। यह भी कहा गया है कि तर्क सूचीतर्क सूची में पैरामीटर के अनुक्रम को बदलकर जावा में विधि ओवरलोडिंग का उपयोग क्या होता है?

(i) में भिन्न हो सकती है। पैरामीटर की संख्या

(ii)। पैरामीटर

(iii) के डेटाटाइप। पैरामीटर का अनुक्रम

मेरी चिंता के बारे में है (iii)।

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

उत्तर

4

(iii) केवल एक विशेष मामला है (ii)।

"int, long, स्ट्रिंग" और "स्ट्रिंग, int, long" (ii) = अलग डेटाटाइप हैं, लेकिन बस प्रकार के समान सेट होते हैं।

लेकिन हाँ, विशिष्ट ओवरलोडिंग भ्रमित कोड की ओर जाता है।

0

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

आपका एपीआई सार्वजनिक हो जाता है, और आपके सभी विधि हस्ताक्षर होते हैं लेकिन एक काफी आम (लेकिन अनियंत्रित) विधि के लिए एक समान है। मान लें कि वे सभी myFunct (स्ट्रिंग, int) हैं और उनमें से एक दुर्घटना से myFunct (int, स्ट्रिंग) होने के लिए होता है। आप उस फ़ंक्शन को पीछे की संगतता के लिए रखना चाहेंगे, लेकिन आप शायद यह भी सुनिश्चित करेंगे कि एक वर्ग में मेरा फंक्शंस (स्ट्रिंग, int) भी सुसंगत बनाए रखे।

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

0

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

अधिकांश प्रोग्रामर एक धारणा के आधार पर कुछ पैरामीटर अनुक्रमों का चयन करेंगे कि ऐसे पैरामीटर किसी विशेष क्रम में अधिक समझ में आते हैं या क्योंकि कुछ गणना के परिणाम के लिए मूल रूप से मूल रूप से महत्वपूर्ण है। एक उदाहरण के रूप में इन अतिभारित तरीकों लें:

int raise(int i, String n); 
int raise(String i, int n); 

आप गणित वर्ग में बहुत जल्दी पर जाना है, किसी अन्य के द्वारा एक मूल्य की परवरिश एक गैर विनिमेय आपरेशन नहीं है (यानी 2^3 = 3^2!)।

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

raise("12", 2); 
raise(12, "2"); 

बेशक यह स्पष्ट कारणों के लिए एक बहुत ही मिश्रित उदाहरण है, लेकिन आप देख सकते हैं कि सिद्धांत में यह उचित है।

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

3

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

मैं जब एक पैरामीटर के रूप में कई डेटा प्रकार मौजूद कर सकते हैं विधि सुविधा प्रयोजनों के लिए एपीआई में अधिक भार का एक बहुत करते हैं: क्या आप मानकों का एक बहुत है, तो

public class Client { 

    public Status get(String request) { 
     return get(new Request(request)); 
    } 

    public Status get(Request request) { 
     // do stuff 
    } 

} 

, और उनमें से कई वैकल्पिक, मैं करूंगा हैं Builder pattern में देखने का सुझाव देते हैं। बिल्डर पैटर्न का इरादा वैकल्पिक मानकों के निर्माण के लिए एक अपरिवर्तनीय वस्तु बनाना है। उदाहरण के लिए:

public String get(String arg0, String arg1, String arg2) { 
    // do stuff 
} 

public String get(String arg0, String arg1) { 
    return method(arg0, arg1, null); 
} 

public String method(String arg0) { 
    return method(arg0, null, null); 
} 

शायद एक बिल्डर के साथ सुधार किया जा सकता है:

class Request { 

    final String arg0; 
    final String arg1; 
    final String arg2; 

    private Request(Builder b) { 
     this.arg0 = b.arg0; 
     this.arg1 = b.arg1; 
     this.arg2 = b.arg2; 
    } 

    // getter methods 

    public static class Builder { 
     String arg0, arg1, arg2; 

     public Builder arg0(String arg) { 
      this.arg0 = arg; 
      return this; 
     } 

     public Builder arg1(String arg) { 
      this.arg1 = arg; 
      return this; 
     } 

     public Builder arg2(String arg) { 
      this.arg2 = arg; 
      return this; 
     } 

     public Request build() { 
      return new Request(this); 
     } 

    } 

} 

class Client { 
    public String get(Request request) { } 
} 

new Client().get(Request.Builder().arg0("arg0").arg1("arg1").arg2("arg2").build()); 

एक और अधिभार है कि मैं जब एक विधि अलग डेटा प्रकार के मापदंडों को स्वीकार कर सकते एक बहुत है:

public String lookup(String variant) { 
    return lookup(Integer.parseInt(variant)); 
} 

public String lookup(int ordinal) { 
    // logic 
} 
0

आप सही हैं, iii आमतौर पर एक मजबूत मामले नहीं बनाते हैं। आमतौर पर, यह नीचे

void save(String key, int value); 
void save(String key, float value); 
void save(String key, byte value); 

आदि बातें दृढ़ता से शो के रूप में आपके द्वारा लिखा गया रखने के लिए आवश्यक है

1

यह भी कहा जाता है कि तर्क सूची
में अलग हो सकता है (iii)। पैरामीटर का अनुक्रम

(iii) बस गलत है। आप पैरामीटर के क्रम को बदलकर अधिभार नहीं बदल सकते हैं। इस उदाहरण को लें:

int add(int x, int y) 
int add(int y, int x) 

यह कानूनी अधिभार नहीं है।

int fill(int number, char c) 
int fill(char c, int number) 

याद रखें पैरामीटर नाम में कोई फर्क नहीं है, इसलिए वास्तव में, यह संकलक करने के लिए इस तरह दिखता है: अब इस उदाहरण पर विचार

int pad(int, char) 
int pad(char, int) 

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


सिर्फ मापदंडों के अनुक्रम बदलकर एक विधि को ओवरलोड करने की कोशिश कर के उपयोग क्या है?

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

सिर्फ इसलिए कि आप यह, आप चाहिए मतलब यह नहीं है कर सकते हैं।

0

पैरामीटर सूची पैरामीटर की संख्या और प्रकारों द्वारा निर्धारित की जाती है। इसलिए यदि आपके पैरामीटर के अलग-अलग प्रकार हैं, तो पैरामीटर को दोबारा ऑर्डर करना एक अलग अधिभार देता है क्योंकि संकलक अलग-अलग स्लॉट में विभिन्न प्रकार देखता है।

f(int a, String b) 

f(String b, int a) 

दोनों कार्यों में दो पैरामीटर हैं लेकिन प्रकार मेल नहीं खाते हैं इसलिए वे वैध ओवरलोड हैं।

आप ऐसा क्यों करना चाहते हैं, यह अक्सर ऐसा होता है कि पैरामीटर का क्रम महत्वपूर्ण है। कोडबेस में मैं बनाए रखता हूं हमारे पास अपवाद हैं जिनके संभावित कारण, एक संदेश, और अन्य पैरामीटर हैं। तो निम्न दो कॉल ही नहीं हैं:

Exception cause; 
String msgFormat = "An error occurred while processing {0}"; 
String recordName = "abc123"; 

throw new ABCException(cause, message, recordName); 

throw new ABCException(message, cause, recordName); 

throw new ABCException(message, recordName); 

throw new ABCException(recordName, message); 

पहला मामला cause में अपवाद का कारण है, message प्रदर्शित करने के लिए संदेश है, और record संदेश के लिए पैरामीटर है। दूसरे मामले में cause और recordName दोनों संदेश के पैरामीटर के रूप में व्याख्या किए जाते हैं। तीसरे मामले में कोई कारण नहीं है और चौथे मामले में कोई कारण नहीं है और message तर्क गलत स्थिति में है और ठीक से संसाधित नहीं किया जाएगा।

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

3

आह! समझ में आता है! मैं

public String buildUrl(String protocol, String host, int port){ 
    return protocol + "://" + host + ":" + port; 
} 

public String buildUrl(String protocol, int port, String host){ 
    return protocol + "://" + host + ":" + port; 
} 

तो, मैं सोच रहा था कि यह बेकार था। लेकिन वहाँ इस तरह के मामले हो सकता है (एक लंबे समय यह साथ आने के लिए :-) लिया) -

public int countTotalTruckWheels(boolean hasSpare, int numberOfTrucks){ 
    if(hasSpare){ 
     return (numberOfTrucks+1)*4; 
    } else{ 
     return numberOfTrucks*4; 
    } 
} 

public int countTotalTruckWheels(int numberOfAxlesInTruck, boolean strongAxle){ 
    if(strongAxle){ 
     //each axle can hold 4 wheels 
     return numberOfAxlesInTruck*4; 
    } else { 
     return numberOfAxlesInTruck*2; 
    } 
} 

यहाँ मापदंडों के डेटाटाइप्स न सिर्फ फिर से आदेश दिया जाता है, लेकिन मानकों के पूरे अर्थ बदल दिया गया है।

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

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