स्थैतिक तरीकों से गुजरने वाली वस्तुएं लाभप्रद क्यों होंगी?


9

एक स्थैतिक विधि का उपयोग करने और एक वस्तु पर विधि को कॉल करने के बजाय एक पैरामीटर के रूप में किसी ऑब्जेक्ट के संदर्भ को पारित करने के लिए एक फायदा क्यों होगा?

स्पष्ट करने के लिए कि मेरा क्या मतलब है, निम्न वर्ग पर विचार करें:

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public void incrementValue() {
        someValue++;
    }
}

स्थैतिक विधि के साथ इस वैकल्पिक कार्यान्वयन की तुलना में:

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public static void incrementValue(SomeClass obj) {
        obj.someValue++;
    }
}

मेरा प्रश्न केवल इस वर्ग तक ही सीमित नहीं है; किसी भी बिंदु पर जहां आप किसी वस्तु को विधि पर कॉल करने के बजाय पास करेंगे, वह वही है जिसमें मैं दिलचस्पी रखता हूं। क्या यह कभी फायदेमंद है? यदि हां, तो क्यों?


1
ऐसा लगता है कि दो तरीकों के साथ कोड गंध समान सटीक काम कर रहा है। यदि स्थैतिक विधि को दूसरी विधि के लिए निर्धारित किया जाता है, तो यह बेकार महसूस होगा, लेकिन जरूरी नहीं कि "बुरा"
नाथन मेरिल

13
@NathanMerrill मुझे लगता है कि आप इस बिंदु को याद कर रहे हैं। वह पूछ रहा है कि क्या कभी ऐसी स्थिति है जहां पहली विधि के बजाय दूसरी विधि का निर्माण और उपयोग करना बेहतर होगा।

@Mego न केवल उदाहरण में दिए गए तरीके; मैं पूछ रहा हूं कि क्या स्थिर तरीकों का उपयोग करते समय कोई भी क्षण है और वस्तुओं को पास करना वस्तुओं पर कॉलिंग विधियों से बेहतर है?
एडिसन क्रम्प

शायद आप विशेष रूप से जावा के लिए पूछ रहे हैं?
एंडरलैंड

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

जवाबों:


34

एक तुच्छ उदाहरण: जब पारित किया गया उदाहरण वैध रूप से अशक्त हो सकता है और आप इसे विधि में शामिल न करने वाले (गैर-तुच्छ) से निपटना चाहते हैं।


1
उदाहरण: String.Compare C # में (मुझे लगता है कि जावा में कुछ ऐसा ही है)
edc65

Objects.equals () और Objects.compare () जावा में उदाहरण हैं - लेकिन वे मूल वर्ग पर नहीं हैं। कम से कम जावा मानक पुस्तकालय में, यह वस्तु की तरह कुछ पर एक उदाहरण विधि है, लेकिन फिर एक वस्तु पर एक स्थिर विधि है आम है रों वर्ग।
११'१६

20

आपके उदाहरण में, उदाहरण विधि एक स्पष्ट विजेता है।

सामान्य स्थिति में, मैं कुछ कारणों के बारे में सोच सकता हूँ जहाँ एक स्थिर विधि उपयुक्त हो सकती है:

  • आप स्थैतिक विधि को किसी अन्य वर्ग में रखना चाहते हैं, क्योंकि आपके पास एक ऐसी स्थिति है जहां यह तर्क को डेटा से अलग करने के लिए समझ में आता है (ध्यान दें: आपका उदाहरण उनमें से एक नहीं है)।

  • आप दो या अधिक वस्तुओं को पारित कर रहे हैं और इस बात पर जोर देना चाहते हैं कि वे समान महत्व के हैं।

  • null एक वैध मान है (उपयोगकर्ता 9000 द्वारा समझाया गया है)।


5

ऐसे तरीकों को शामिल करना बुद्धिमान होगा जो वस्तु की स्थिति को स्थैतिक विधि के बजाय उदाहरण के तरीकों के रूप में बदलते हैं ।

हालाँकि हम स्थैतिक तरीकों के उदाहरण पा सकते हैं जो कि pureविधियाँ हैं और वस्तु को इनपुट के रूप में लेते हैं, जैसे कि जब हमें कुछ वैध नियमों के आधार पर वस्तु को तुरंत हटाने की आवश्यकता होती है। उदाहरण के लिए, .NET में DateTime.TryParse(String s, DateTime d)ऑब्जेक्ट को वेरिफाई करने और उसे इंस्टेंट करने की विधि है। लेकिन पैरामीटर DateTime dको स्पष्ट रूप से चिह्नित किया गया है out

एक और मामला तब हो सकता है जब हम वस्तुओं की तुलना करते हैं और उदाहरण के लिए तुलनात्मक परिणाम के बूलियन / पूर्णांक मान के बजाय रिटर्न ऑब्जेक्ट के रूप में वांछित वस्तु प्राप्त करना चाहते हैं Team.GetHigherScorer(teamA, teamB).IncreaseRanking()। इससे क्लीनर होगा:

int compareResult = teamA.compareScoreWith(teamB);
if (compareResult == 1)
    teamA.IncreaseRanking();
else if (compareResult == -1) 
    teamB.IncreaseRanking();

(मामले को "सादगी के लिए बाहर" छोड़ कर)।


1
एक "संपूर्ण वस्तु" पास नहीं करता है। आप मेमोरी में एक जगह के संदर्भ को पास करते हैं, जो कि बहुत कम मात्रा में डेटा पास हो रहा है। मुझे लगता है कि प्रदर्शन पर प्रभाव के बारे में निश्चित नहीं है, लेकिन फिर भी ... भी, "आउट" का अर्थ क्या है?
Addison Crump

1
मैंने अपने बयान से 'संपूर्ण' शब्द को हटा दिया, यह भ्रामक था। मैंने प्रदर्शन या आकार का कभी इरादा नहीं किया, इसका जवाब विशुद्ध रूप से प्रोग्रामिंग प्रथाओं पर आधारित है। वैसे भी, एक पैरामीटर पैरामीटर के रूप में प्रयोग किया जाने outवाला .Netकीवर्ड है। यह बताता है कि पैरामीटर संदर्भ द्वारा पारित किया गया है। विवरण के लिए देखें msdn.microsoft.com/en-us/library/t3c3bfhx.aspx
wonderbell

4
पहला वाक्य बस गलत है। अगर हमारे पास है class C { int x; static void M() { तो M पूरी तरह से उपयोग करने में सक्षम है x। उदाहरण के लिए int y = (new C()).x;कानूनी है।
एरिक लिपर्ट

@EricLippert :) मुझे यकीन है कि आप जानते हैं कि मेरा क्या मतलब है। यह आश्चर्यजनक है कि स्वामी लाइनों के बीच कैसे पढ़ सकते हैं। हो सकता है कि मुझे उस वाक्य को संपादित करने की आवश्यकता हो। स्पष्टीकरण के लिए, ऐसा कुछ static void M() { this.x = 1; }संभव नहीं है।
वंडरबेल

1
@wonderbell: नहीं, मुझे यकीन है कि मुझे नहीं पता था कि आपका क्या मतलब है। मुझे पता था कि आपने क्या लिखा है। मैं ध्यान देता हूं कि this.xगलत नहीं है क्योंकि xएक्सेस नहीं किया जा सकता है, लेकिन thisमौजूद नहीं है। यह बिल्कुल पहुंच का सवाल नहीं है , यह अस्तित्व का सवाल है
एरिक लिपर्ट

4

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

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