मुझे कक्षा को 'स्थिर' क्यों और कब बनाना चाहिए? कक्षाओं पर 'स्थिर' कीवर्ड का उद्देश्य क्या है?


47

staticकई भाषाओं में एक सदस्य पर कीवर्ड मतलब है कि आप उस वर्ग का एक उदाहरण है कि सदस्य की पहुंच है करने में सक्षम हो नहीं बनाना चाहिए। हालाँकि, मुझे पूरी कक्षा बनाने का कोई औचित्य नहीं दिखता है static। मुझे कक्षा क्यों और कब बनानी चाहिए static?

कक्षा बनाने से मुझे क्या लाभ होगा static? मेरा मतलब है, एक स्थिर वर्ग की घोषणा करने के बाद, किसी को अभी भी सभी सदस्यों की घोषणा करनी चाहिए, जो वह बिना किसी इंस्टेंटेशन के पहुँच प्राप्त करना चाहते हैं, जैसा कि स्थैतिक भी।

इसका मतलब यह है कि Mathडेवलपर्स कोड को प्रभावित किए बिना, उदाहरण के लिए, वर्ग को सामान्य (स्थिर नहीं) घोषित किया जा सकता है। दूसरे शब्दों में, एक वर्ग को स्थिर या सामान्य बनाना डेवलपर्स के लिए पारदर्शी है।


यदि आप फंक प्रोग शैली में ला रिच हिकी कोडिंग कर रहे हैं, तो यह उपयोगी हो सकता है।
अय्यूब

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

जवाबों:


32

यह उपयोगकर्ताओं को यह स्पष्ट करता है कि कक्षा का उपयोग कैसे किया जाता है। उदाहरण के लिए, निम्नलिखित कोड लिखना पूर्ण बकवास होगा:

Math m = new Math();

C # को इसके लिए मना करने की आवश्यकता नहीं है लेकिन चूंकि यह बिना किसी उद्देश्य के कार्य करता है, इसलिए उपयोगकर्ता को यह भी बता सकता है। कुछ लोग (मेरे सहित) दर्शन का पालन करते हैं कि प्रोग्रामिंग भाषाओं (और एपीआई…) को गलत का उपयोग करने के लिए उन्हें जितना संभव हो उतना प्रतिबंधात्मक होना चाहिए: केवल अनुमति वाले संचालन तब होते हैं जो सार्थक होते हैं और (उम्मीद है) सही होते हैं।


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

19
@ फिर पुस्तकालय बुरी तरह से डिजाइन किया गया है। विस्तार के लिए डिज़ाइन नहीं की गई कक्षाएं अंत में काम नहीं करती हैं, इसलिए कक्षा sealedको पहले स्थान पर सर्वश्रेष्ठ बनाएं । मैं स्वीकार करता हूं कि सभी लोग इस भावना से सहमत नहीं हैं लेकिन टिप्पणी इस पर चर्चा करने के लिए एक अच्छी जगह नहीं है। लेकिन staticइस समस्या के मामले में भी खुद को नहीं छोड़ता है: तात्कालिकता कभी भी समझ में नहींSystem.Math आएगी ।
कोनराड रुडोल्फ

1
@ कोनार्ड, यदि आप Mathकक्षा के सभी सदस्यों को वर्ग को स्थिर घोषित किए बिना स्थिर घोषित करते हैं Math, तब भी आप इसका उपयोग कर सकते हैं, बिना तात्कालिकता के।
सईद नेमाटी

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

3
@ सईद आइए इसे घुमाएँ: मेरा प्रस्ताव है कि आप मेरे उत्तर को फिर से पढ़ें क्योंकि आपको लगता है कि यह गलत समझा गया है: आपकी टिप्पणियाँ मेरे उत्तर से असंबंधित हैं। मैंने कभी नहीं कहा कि आपको लिखने की ज़रूरत है new Math()
कोनराड रुडोल्फ

24

StackOverflow इस विषय पर एक महान चर्चा है । संदर्भ में आसानी के लिए, मैं इसे कॉपी और पेस्ट करूंगा, इसके लेखक मार्क एस रासमुसेन की ओर से :

मैंने पहले के धागे में स्थिर वर्गों के अपने विचार लिखे :

मैं स्टैटिस्टिक मेथड से भरे यूटीलिटी क्लासेज से प्यार करता था। उन्होंने सहायक विधियों का एक बड़ा समेकन किया जो अन्यथा अतिरेक और रखरखाव नरक का कारण बन जाएगा। वे उपयोग करने के लिए बहुत आसान हैं, कोई तात्कालिकता नहीं, कोई निपटान नहीं, बस फायर'एन'फॉरगेट। मुझे लगता है कि यह एक सेवा उन्मुख वास्तुकला बनाने का मेरा पहला अनजाना प्रयास था - बहुत सारी स्टेटलेस सेवाएं जो सिर्फ अपना काम करती थीं और कुछ नहीं। हालाँकि सिस्टम बढ़ता है, ड्रेगन आ रहे हैं।

बहुरूपता

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

इंटरफ़ेस मिटा देता है

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

परिक्षण

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

फोस्टर खिलता है

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

पैरामीटर रेंगना

शुरू करने के लिए, उस छोटे से प्यारे और निर्दोष स्थिर तरीके से एक एकल पैरामीटर लिया जा सकता है। जैसे-जैसे कार्यक्षमता बढ़ती है, कुछ नए पैरामीटर जोड़े जाते हैं। जल्द ही आगे के पैरामीटर जोड़े जाते हैं जो वैकल्पिक होते हैं, इसलिए हम विधि का अधिभार बनाते हैं (या बस उन भाषाओं में डिफ़ॉल्ट मान जोड़ें, जो उनका समर्थन करते हैं)। लंबे समय से पहले, हमारे पास एक विधि है जो 10 पैरामीटर लेती है। केवल पहले तीन वास्तव में आवश्यक हैं, पैरामीटर 4-7 वैकल्पिक हैं। लेकिन अगर पैरामीटर 6 निर्दिष्ट किया गया है, तो 7-9 को भी भरे जाने की आवश्यकता है ... क्या हमने ऐसा करने के एकल उद्देश्य के साथ एक वर्ग बनाया था जो इस स्थिर विधि ने किया था, हम इसे आवश्यक मापदंडों में ले जाकर हल कर सकते हैं निर्माता, और उपयोगकर्ता को एक ही समय में कई अन्योन्याश्रित मूल्यों को सेट करने के लिए गुणों, या विधियों के माध्यम से वैकल्पिक मान सेट करने की अनुमति देता है। इसके अलावा,

उपभोक्ताओं को बिना किसी कारण वर्गों का एक उदाहरण बनाने की मांग करना

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

केवल एक सिथ निरपेक्षता में व्यवहार करता है

बेशक, मेरे स्थिर तरीकों को नापसंद करने के अपवाद हैं। ट्रू यूटिलिटी क्लासेस जो ब्लोट के लिए कोई जोखिम नहीं उठाती हैं, वे स्टैटिक तरीकों के लिए उत्कृष्ट मामले हैं- System.Convert एक उदाहरण के रूप में। यदि आपकी परियोजना भविष्य के रखरखाव के लिए कोई आवश्यकता नहीं है, तो समग्र वास्तुकला वास्तव में बहुत महत्वपूर्ण नहीं है - स्थिर या गैर स्थिर, वास्तव में कोई फर्क नहीं पड़ता - विकास की गति, हालांकि।

मानकों, मानकों, मानकों!

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


12
हम्म, मुझे नहीं पता कि मैं यहां एक संपूर्ण उत्तर को कॉपी और पेस्ट करूंगा। शायद लिंक और पैराफेरेस में एक वैकल्पिक दृष्टिकोण शामिल है क्योंकि आप "चर्चा" का उल्लेख करते हैं, अपना खुद का अनुभव साझा करते हैं?
कॉर्बिन मार्च

2
"केवल एक मिथक निरपेक्षता में सौदा करता है" - मैंने ऐसा नहीं देखा था जो पहले की तरह इस्तेमाल किया गया था .... लेकिन यह सही है। मुझे योग्य बनाया।
ब्रुक

4
@ कॉर्बिन: मार्क का शानदार जवाब था। मैंने उसे श्रेय दिया और मैंने संदर्भ की आसानी के लिए कॉपी / पेस्ट किया। इस मामले पर मेरे अपने विचार मार्क से मेल खाते हैं। मैं बहस शुरू करने के अलावा आपकी टिप्पणी का बिंदु नहीं देखता।
रिक

1
@ रिक: कॉपी किया गया उत्तर काफी लंबा है, और यह निश्चित रूप से मदद करेगा। बस एक वाक्य जैसे "यह सिर्फ इतना नहीं है कि वे वास्तव में उपयोगी नहीं हैं, वे नुकसान भी पहुंचा सकते हैं, क्योंकि यह एसओ पोस्ट दिखाता है:" मुझे जल्दी से इसे छोड़ देना चाहिए क्योंकि मुझे लगता है कि यह वह जानकारी नहीं है जिसकी मुझे तलाश थी।
ब्लब

@ साइमन: LOL I 1 + 'अपना पोस्ट एड करें। कुछ बेवकूफी पर बहस करने की कोशिश में, मैं सिर्फ सहमत हूँ। :) उम्मीद है कि मूल पोस्टर ने मेरा उत्तर / कॉपी और पेस्ट उपयोगी पाया।
रिक

16

मुझे आश्चर्य है कि किसी और ने यह उल्लेख नहीं किया है कि staticकक्षाएं विस्तार विधियों की अनुमति देती हैं - एक मौजूदा प्रकार को सुरक्षित रूप से विस्तारित करना ( इंटरफेस में विधि परिभाषाओं को शामिल करना) जो आपके पास हैं। मसलन, स्काला में क्या है

trait MyFoo {
  def foo: Int
  def plusFoo(a: Int) = foo + a
}

C # के रूप में व्यक्त किया जा सकता है

public interface IMyFoo {
  int Foo();
}

public static class MyFooExtensions {
  public static int PlusFoo(this IMyFoo f, int a) {
    return f.Foo() + a;
  }
}

तुम पाताल में सुई पा गए। +1
सईद नेमाटी

3

मेरे लिए, एक स्थिर वर्ग (C # में) एक फ़ंक्शन को कॉल करने की तरह है।

उदाहरण के लिए

public static string DoSomething(string DoSomethingWithThisString){}

मैं एक स्ट्रिंग में गुजरता हूं और एक स्ट्रिंग वापस प्राप्त करता हूं। सब कुछ उस पद्धति में निहित है। सदस्य चर, आदि के लिए कोई पहुँच नहीं

ईमानदारी से, मेरे लिए ज्यादातर इसका उपयोग कोड की लाइनों को कम करने के लिए किया गया है:

क्यों कर:

MyClass class = new MyClass();
String s = class.DoSomething("test");

जब मैं यह कर सकता हूं:

String s = MyClass.DoSomething("test");

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

मार्क एस अंक मान्य हैं, लेकिन मेरे लिए अगर मेरे पास कुछ उपयोगिता विधियां हैं, तो यह दिखावा करना आसान है कि मैं उन्हें एक लाइनर के रूप में संदर्भित करने के लिए एक फ़ंक्शन कॉल कर रहा हूं।

यह सरल हो सकता है, लेकिन यह है कि ज्यादातर मैंने कैसे उपयोग किया है static


1
नया MyClass ()। DoSomething ("परीक्षण") अभी भी मान्य है। मैं टेस्ट डेटा बिल्डर्स के लिए इसका बहुत उपयोग करता हूं।
JoanComasFdz
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.