2013-05-19 13 views
26

क्या ए और बी के बीच कोई अंतर है?निजी कन्स्ट्रक्टर वाले एक वर्ग और निजी कन्स्ट्रक्टर वाले सीलबंद वर्ग के बीच क्या अंतर है?

कक्षा एक निजी निर्माता है:

class A 
{ 
    private A() 
    { } 
} 

कक्षा बी बंद है और एक निजी निर्माता है:

sealed class B 
{ 
    private B() 
    { } 
} 
+0

आप निजी कन्स्ट्रक्टर के साथ पहली जगह क्यों चाहते हैं? –

+5

@ मार्कसमेसेकानन कक्षा में सार्वजनिक स्थैतिक फैक्ट्री विधि हो सकती है जिसे क्लाइंट का उदाहरण बनाने का एकमात्र तरीका होना चाहिए। –

+3

@ मार्कसमेसेकान [सिंगलेट्स] (http://msdn.microsoft.com/en-us/library/ff650316.aspx) –

उत्तर

39

हाँ A को नेस्टेड क्लास द्वारा विरासत में प्राप्त किया जा सकता है, जबकि B को विरासत में नहीं मिला जा सकता है। यह पूरी तरह से कानूनी है:

public class A { 
    private A() { } 

    public class Derived : A { } 
} 

ध्यान दें कि किसी भी कोड एक new A.Derived() बना सकते हैं या A.Derived से विरासत (अपने निर्माता सार्वजनिक है) सकता है, लेकिन A के पाठ स्रोत के बाहर कोई अन्य वर्गों A से सीधे वारिस कर सकते हैं। एक वर्ग बंद है

public abstract class A { 
    private A() { } 

    public abstract void DoSomething(); 

    private class OneImpl : A { 
    public override void DoSomething() { Console.WriteLine("One"); } 
    } 

    private class TwoImpl : A { 
    public override void DoSomething() { Console.WriteLine("Two"); } 
    } 

    public static readonly A One = new OneImpl(); 
    public static readonly A Two = new TwoImpl(); 
} 
+0

खुशी से मेरे +1 की पेशकश :-) – Jon

+0

हाहा! अब यह * नहीं * इसमें शामिल है कि आप वास्तव में ऐसा करना चाहते हैं (हालांकि आमतौर पर नहीं)।+1 :) –

+2

अनिवार्य रूप से, यह ए पर अन्य रचनाकार प्रदान करने जैसा ही है, सिवाय इसके कि सुपर "फैंसी" नेस्टेड क्लास आधारित कन्स्ट्रक्टर –

5

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

Inheritance (C# Programming Guide)

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

Private Constructors (C# Programming Guide)

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

+0

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

+0

आप न तो ए या बी प्राप्त नहीं कर सकते हैं आप निजी कन्स्ट्रक्टर की वजह से ए डर्बी नहीं कर सकते हैं। सवाल यह हो सकता है: यदि कोई निजी कन्स्ट्रक्टर वाला वर्ग है तो क्या आप इसे सील कर चुके हैं तो कोई अंतर है। – jannagy02

+0

@ jannagy02: मैं अपडेट कर रहा था क्योंकि आप अपनी टिप्पणी टाइप कर रहे थे :-) – Harrison

1

sealed कक्षा को तत्काल किया जा सकता है लेकिन एक निजी कन्स्ट्रक्टर वाला वर्ग नहीं हो सकता है। वे दोनों विरासत की अनुमति नहीं देते हैं, लेकिन यह एक निजी कन्स्ट्रक्टर का उद्देश्य नहीं है।

आप एक निजी निर्माता का उपयोग करने का कारण तत्काल रोकना है। इसका उपयोग अक्सर स्थिर कारखाने के तरीकों में किया जाता है, जहां आपको उदाहरण बनाने के लिए MyClass::Create(...) पर कॉल करना होगा।

इसका सीलिंग करने के लिए कुछ भी नहीं है, जो विरासत को रोकता है। यदि आप विरासत को रोकने के लिए एक निजी निर्माता का उपयोग करते हैं, तो आप गलत दृष्टिकोण का उपयोग कर रहे हैं। विरासत के लिए एक निजी कन्स्ट्रक्टर के आसपास पाने के तरीके हैं।

4

कोड विश्लेषण के साथ करने के लिए आपको एक छोटा सा अंतर मिल सकता है।

इस कोड पर विचार करें:

public class Base 
{ 
    public virtual void Function() 
    { 
    } 
} 

public class Derived: Base 
{ 
    public static Derived Create() 
    { 
     return new Derived(); 
    } 

    private Derived() 
    { 
     // Code analysis warning: CS2214 "Do not call overridable methods in constructors". 
     Function(); 
    } 
} 

वहाँ व्युत्पन्न निर्माता के लिए चेतावनी एक कोड विश्लेषण है, क्योंकि हम इसे से एक आभासी विधि है, जो एक बुरी बात है तक पहुँच रहे हैं।

हालांकि, अगर आप Derived सील कर देते हैं, तो कोड विश्लेषण चेतावनी दूर हो जाती है।

तो आपके लिए एक छोटा और प्रदूषित अंतर है। ;)

0

है, यह एक वर्ग जो निकला है परिभाषित करने के लिए संभव नहीं होगा:

कुछ इस तरह के लिए एक विशिष्ट उपयोग enum की तरह मान लेकिन जो कस्टम व्यवहार हो सकता है के साथ एक वर्ग है इसमें से। एक निजी कन्स्ट्रक्टर वाला एक वर्ग कक्षा के भीतर फैक्ट्री विधियों द्वारा तत्काल किया जा सकता है, न ही नेस्टेड कक्षाओं द्वारा विरासत में प्राप्त किया जाता है (जो, उनके पहुंच स्तर और रचनाकारों के आधार पर, बाहरी कोड द्वारा विरासत योग्य हो सकता है)। इसके अतिरिक्त, कोड के बाहर मनमाने ढंग से कक्षाएं घोषित कर सकती हैं जो इससे प्राप्त होती हैं और new() बाधा को संतुष्ट करती हैं। यदि व्युत्पन्न वर्ग बेस कंस्ट्रक्टर को कॉल नहीं कर सकता है, तो इसके स्वयं के रचनाकारों के पास अपवाद, क्रैश या लटका फेंकने के अलावा कोई विकल्प नहीं होगा, लेकिन वास्तव में एक उदाहरण बनाने के प्रयास किए जाने तक ऐसा व्यवहार पता लगाने योग्य नहीं होगा; कोड ठीक संकलित होगा।

0
public class Test 
{ 


    private Test() 
    { 
     Debug.WriteLine("private constructor has been called in class Test"); 
    } 

    public virtual string Run() 
    { 
     return "Test.Run"; 
    } 

    public static Test GetTestRequest() 
    { 
     return new Test(); 
    } 

    public static DerivedTest GetDerivedTestRequest() 
    { 
     return new DerivedTest(); 
    } 

    public class DerivedTest:Test 
    { 
     public DerivedTest() 
     { 
      Debug.WriteLine("public constructor has been called in derived class DerivedTest."); 
     } 

     public override string Run() 
     { 
      return "DerivedTest.Run"; 
     } 
    } 
} 

डीबग। राइटलाइन (टेस्ट.गेटटेस्टआरक्वेट()। रन()); डीबग। राइटलाइन (टेस्ट। गेटडिवेटेड टेस्टआरक्वेट()। रन());

============================================== ============== आउटपुट:

निजी निर्माता Test.Run

वर्ग टेस्ट में बुलाया गया है

निजी निर्माता वर्ग टेस्ट में बुलाया गया है सार्वजनिक निर्माता किया गया है व्युत्पन्न वर्ग DerivedTest में बुलाया। DerivedTest.Run

तो, एक नेस्टेड क्लास एक बाहरी बेस क्लास से प्राप्त किया जा सकता है जिसमें एकमात्र निजी कन्स्ट्रक्टर होता है।

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