2013-02-12 36 views
18

मुझे बताया गया था कि static विधियां final हैं और इसलिए इसे ओवरराइड नहीं किया जा सकता है। क्या यह सच है?क्या सी # में एक स्थिर विधि ओवरराइड की जा सकती है?

  1. क्या कोई स्थिर विधि ओवरराइड करने का बेहतर उदाहरण दे सकता है?

  2. यदि स्थैतिक विधियां केवल क्लास विधियां हैं, तो उन्हें रखने का वास्तविक उपयोग क्या है?

+1

नहीं, उन्हें ओवरराइड नहीं किया जा सकता है। वे वर्ग के साथ जुड़े हुए हैं, वस्तु के साथ नहीं। वास्तविक उपयोग के लिए –

+0

: आप क्लास इंस्टेंस के बिना एक स्थिर विधि को कॉल कर सकते हैं। – Najzero

+0

धन्यवाद। मैं समझता हूं [क्या एक स्थिर विधि है] (http://stackoverflow.com/a/4124118/2061309), स्लाक्स द्वारा दिया गया सबसे अच्छा उदाहरण। तो एक स्थैतिक विधि को ओवरराइड करने के बारे में मेरे प्रश्न के लिए (यदि बायडेफॉल्ट अंतिम है, तो उपयोगकर्ता इसे अंतिम नहीं बनाते) - क्या इसका मतलब यह है कि इस वर्ग का कोई उप-वर्ग नहीं है जो स्थैतिक रखता है, उसी हस्ताक्षर के साथ एक स्थिर विधि को परिभाषित कर सकता है? – aspiring

उत्तर

17

(1) स्टेटिक विधियों को ओवरराइड नहीं किया जा सकता है, तो वे आपके नए MockRoleService को वास्तविक सेवा के साथ स्वैप कर सकते हैं, हालांकि उन्हें 'नए' कीवर्ड का उपयोग करके छुपाया जा सकता है। अधिकतर ओवरराइडिंग विधियों का अर्थ है कि आप आधार प्रकार का संदर्भ देते हैं और व्युत्पन्न विधि को कॉल करना चाहते हैं। चूंकि स्थैतिक प्रकार का हिस्सा हैं और वे vtable लुकअप के अधीन नहीं हैं जो समझ में नहीं आता है।

उदा। स्टैटिक्स ऐसा नहीं कर सकते:

public class Foo { 
    public virtual void Bar() { ... } 
} 
public class Bar : Foo { 
    public override void Bar() { ... } 
} 

// use: 
Foo foo = new Bar(); // make an instance 
foo.Bar(); // calls Bar::Bar 

क्योंकि स्टैटिक्स उदाहरणों पर काम नहीं करते, तो आप हमेशा Foo.Bar या Bar.Bar स्पष्ट रूप से निर्दिष्ट। तो ओवरराइडिंग का कोई मतलब नहीं है (इसे कोड में व्यक्त करने का प्रयास करें ...)।

(2) स्थिर तरीकों के लिए अलग-अलग उपयोग हैं। उदाहरण के लिए, इसका उपयोग सिंगलटन पैटर्न में एक प्रकार का एक उदाहरण प्राप्त करने के लिए किया जा रहा है। एक और उदाहरण 'स्थैतिक शून्य मुख्य' है, जो आपके कार्यक्रम में मुख्य पहुंच बिंदु है।

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

[अद्यतन]

एक साधारण छुपा उदाहरण:

public class StaticTest 
{ 
    public static void Foo() { Console.WriteLine("Foo 1"); } 
    public static void Bar() { Console.WriteLine("Bar 1"); } 
} 

public class StaticTest2 : StaticTest 
{ 
    public new static void Foo() { Console.WriteLine("Foo 2"); } 
    public static void Some() { Foo(); Bar(); } // Will print Foo 2, Bar 1 
} 

public class TestStatic 
{ 
    static void Main(string[] args) 
    { 
     StaticTest2.Foo(); 
     StaticTest2.Some(); 
     StaticTest.Foo(); 
     Console.ReadLine(); 
    } 
} 

ध्यान दें कि अगर आप कक्षाओं static बनाने के लिए, यदि आप ऐसा नहीं कर सकते हैं। स्टेटिक वर्गों को object से प्राप्त करना होगा।

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

+0

मुझे ओवरराइडिंग का वह उदाहरण देने के लिए धन्यवाद। हाँ मैं कोड में कोशिश कर रहा हूँ। तो यह अधिकार प्राप्त करने के लिए, 1) ** हम किसी भी अन्य गैर स्थैतिक वर्ग की तरह एक स्थिर वर्ग उप-वर्ग कर सकते हैं **? 2) हम पैरेंट क्लास स्टेटिक विधियों को ओवरराइड किए बिना स्थिर तरीकों का उपयोग कर सकते हैं लेकिन नए कीवर्ड का उपयोग करके उन्हें छुपा सकते हैं। – aspiring

+0

मैंने कुछ और स्पष्टीकरण और एक उदाहरण जोड़ा। (1) नहीं, आप एक स्थिर वर्ग उप-वर्ग नहीं कर सकते हैं, लेकिन आप स्थिर सदस्यों को छुपा सकते हैं। (2) हां, आपको दूसरे उदाहरण का प्रयास करना चाहिए, यह बताता है कि यह कैसे व्यवहार करता है। – atlaste

+3

कब यह फू <-> बार बकवास अंत ??? उदाहरण के लिए फूरबार का उपयोग करना बंद करें, प्रत्येक मामले में बार और फू या तो कक्षाएं या उप-वर्ग या कार्य या विधियां हैं। तो बिंदु क्या है ??? ओवरराइडिंग के लिए उप-वर्गीकरण और कार्यों के लिए जानवरों का उपयोग करें। 10x –

5

आप एक स्थिर विधि को ओवरराइड नहीं करते हैं। आप इसे छुपाते हैं अधिक जानकारी के लिए this answer देखें।

कुछ कारणों स्थिर तरीकों का उपयोग करने के लिए:

  1. वे उदाहरण के तरीकों की तुलना में एक little bit faster हैं। यह भी देखें msdn article जो इसे वापस करने के लिए प्रदर्शन संख्या देता है (इनलाइन स्टेटिक कॉल औसत 0.2 एनएस, स्थिर कॉल औसत 6.1ns, रेखांकित उदाहरण कॉल औसत 1.1 एनएस, इंस्टेंस कॉल औसत 6.8 एनएस)
  2. लिखने के लिए कम वर्बोज़ - डॉन ' उन्हें प्राप्त करने के लिए कक्षा को तत्काल करने की आवश्यकता नहीं है (और तात्कालिकता प्रदर्शन को भी प्रभावित कर सकती है)
+0

मुझे उदाहरण विधियों के साथ कोई समस्या नहीं है। मैंने सीखा कि 'स्थिर' वर्ग को तत्काल नहीं किया जा सकता है। लेकिन आपने उल्लेख किया कि "स्थैतिक विधियां यह है कि यह आपके ऐप में केवल एक बार तत्काल हो जाती है" .. तो अब मैं उलझन में हूं। क्या आप 'सिस्टम का उपयोग कर रहे हैं।' मथ; 'स्थिर तरीके से कह रहे हैं? मैं गणित वर्ग के सदस्यों Math.Abs ​​() को एक ही कक्षा में कई बार तत्काल किए बिना उपयोग कर रहा हूं। 1) तो क्या आप कृपया स्पष्ट कर सकते हैं कि *** *** "एक बार तत्काल" *** से क्या मतलब है? 2) क्या एक स्टेटिक क्लास उप-वर्ग हो सकता है? क्या यह सब-क्लास को एक स्थिर वर्ग के लिए समझ में आता है? – aspiring

+1

मेरा संपादन देखें। मुझे एक स्थैतिक विधि के साथ "तत्काल" शब्द का उपयोग नहीं करना चाहिए था। यह कहना सही है कि यह केवल एक बार बनाया गया है। –

+1

सभी * विधियां * केवल एक बार "बनाई गई" हैं। यहां तक ​​कि गैर स्थैतिक तरीकों में अस्तित्व में कोड की केवल एक प्रति है (आईएल कोड जो संकलन-समय पर बनाया गया है और मशीन कोड में * एक बार * रन-टाइम पर परिवर्तित किया गया है)। कोड और डेटा भ्रमित मत करो! एक गैर स्थैतिक विधि केवल एक वस्तु के उदाहरण के माध्यम से * कॉल करने योग्य * है, लेकिन यह छिपा हुआ "यह" पॉइंटर है जो इसे पारित किया जाता है। कोड स्वयं "स्थैतिक" है जिसमें यह निश्चित और सिंगलटन है। –

5

ठीक है आप एक स्थिर विधि को ओवरराइड नहीं कर सकते हैं। एक स्थैतिक विधि वर्चुअल नहीं हो सकती है, क्योंकि यह कक्षा के उदाहरण से संबंधित नहीं है।

व्युत्पन्न वर्ग में "ओवर्रिडेन" विधि वास्तव में एक नई विधि है, जो बेस क्लास (इसलिए नया कीवर्ड) में परिभाषित एक से संबंधित नहीं है।

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

यदि आप स्थिर तरीकों से अवगत होने के बारे में सोचते हैं, तो यह वास्तव में समझ में नहीं आता है; वर्चुअल प्रेषण के लिए आपको किसी ऑब्जेक्ट के वास्तविक जांच की आवश्यकता है।

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

+0

धन्यवाद। मेरे लिए पचाने के लिए यह थोड़ा सा स्तर है, लेकिन जिस तरह से मैं इसे प्राप्त करूंगा :) पीएस: और मैं निश्चित रूप से उस मामले में अपनी कक्षा में रहना चाहता हूं। पाया [यह पोस्ट जावा संदर्भ में भी है।] (Http://www.xyzws.com/Javafaq/can-static-methods-be-overridden/1) – aspiring

+1

हेहे अच्छी तरह से मैं भी सीख रहा हूँ C# .. मैं 22 साल का हूँ बूढ़े और कंपनी में काम कर रहे हैं ... सरल चीजों के माध्यम से आप इसे कदम से कदम प्राप्त करेंगे। – Neel