नेस्टेड क्लासेस का उपयोग कब और क्यों करना है?


30

ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग का उपयोग करना हमारे पास एक वर्ग (नेस्टेड क्लास) के अंदर एक वर्ग बनाने की शक्ति है, लेकिन मैंने अपने 4 वर्षों के कोडिंग अनुभव में कभी भी नेस्टेड क्लास नहीं बनाया है।
नेस्टेड क्लास किसके लिए अच्छे हैं?

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

किस परिदृश्य में नेस्टेड वर्गों का उपयोग किया जाना चाहिए या वे अन्य तकनीकों के उपयोग के मामले में अधिक शक्तिशाली हैं?


1
आपके पास कुछ अच्छे उत्तर हैं और मुझे कभी-कभी सिर्फ कुछ कामकाजी वर्ग या अकड़ मिलेगी जो मुझे केवल कक्षा के अंदर की जरूरत है।
पापाराज़ो

जवाबों:


19

नेस्टेड वर्गों की मुख्य विशेषता यह है कि वे बाहरी वर्ग के निजी सदस्यों तक पहुँच सकते हैं जबकि एक वर्ग की पूरी शक्ति होती है। इसके अलावा वे निजी हो सकते हैं जो कुछ परिस्थितियों में बहुत शक्तिशाली शक्तिशाली एनकैप्सुलेशन के लिए अनुमति देता है:

यहां हम सेटर को पूरी तरह से कारखाने में बंद कर देते हैं क्योंकि निजी है कोई भी उपभोक्ता इसे डाउनकास्ट कर सकता है और सेटर तक पहुंच सकता है, और हम पूरी तरह से नियंत्रित कर सकते हैं कि क्या अनुमति है।

public interface IFoo 
{
    int Foo{get;}      
}
public class Factory
{
    private class MyFoo : IFoo
    {
        public int Foo{get;set;}
    }
    public IFoo CreateFoo(int value) => new MyFoo{Foo = value};
}

इसके अलावा यह एक नियंत्रित वातावरण में तीसरे पक्ष के इंटरफेस को लागू करने के लिए उपयोगी है जहां हम अभी भी निजी सदस्यों तक पहुंच सकते हैं।

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

public class Outer
{
    private int _example;
    private class Inner : ISomeInterface
    {
        Outer _outer;
        public Inner(Outer outer){_outer = outer;}
        public int DoStuff() => _outer._example;
    }
    public void DoStuff(){_someDependency.DoBar(new Inner(this)); }
}

ज्यादातर मामलों में मुझे उम्मीद है कि प्रतिनिधि ऐसा करने के लिए एक साफ-सुथरा तरीका होगा जो आप दूसरे उदाहरण में दिखा रहे हैं
बेन आरोनसन

@BenAaronson आप प्रतिनिधियों का उपयोग करके एक यादृच्छिक इंटरफ़ेस कैसे लागू करेंगे?
एसेन स्कोव पेडरसन

@EsbenSkovPedersen आपके उदाहरण के लिए, उदाहरण के लिए, इसके बजाय Outer, आप एक पास Func<int>करेंगे, जो सिर्फ होगा() => _example
बेन आरोनसन

@BenAaronson इस अत्यंत सरल मामले में आप सही हैं लेकिन अधिक जटिल उदाहरणों के लिए, बहुत सारे प्रतिनिधि अनाड़ी हो जाते हैं।
एबेन स्कोव पेडरसन

@EsbenSkovPedersen: आपके उदाहरण में कुछ योग्यता है, लेकिन IMO का उपयोग केवल उन मामलों में किया जाना चाहिए, जहां Innerगैर-नेस्टेड बना रहे हैं और internalकाम नहीं करते हैं (यानी जब आप विभिन्न असेंबली के साथ काम नहीं कर रहे हैं)। घोंसले के शिकार वर्गों से हिट की पठनीयता का उपयोग internal(जहां संभव हो) की तुलना में कम अनुकूल होता है ।
Flater

23

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

मेरा मानना ​​है कि यह अक्सर एक ऐसी विधि को लागू करने के लिए होता है जो किसी इंटरफ़ेस को लागू करने वाली वस्तु को लौटाता है, और हम उस वस्तु के ठोस प्रकार को छिपाए रखना चाहते हैं क्योंकि यह कहीं और उपयोगी नहीं होगा।

IEnumerable को लागू करना इसका एक अच्छा उदाहरण है:

class BlobOfBusinessData: IEnumerable<BusinessDatum>
{
    public IEnumerator<BusinessDatum> GetEnumerator()
    {
         return new BusinessDatumEnumerator(...);
    }

    class BusinessDatumEnumerator: IEnumerator<BusinessDatum>
    {
        ...
    }
}

BlobOfBusinessDataठोस BusinessDatumEnumeratorप्रकार के बारे में जानने या देखभाल करने के बाहर किसी के पास कोई कारण नहीं है , इसलिए हम इसे अंदर रख सकते हैं BlobOfBusinessData

इसका मतलब यह नहीं था कि "सर्वोत्तम-प्रथाओं" का उदाहरण कैसे IEnumerableठीक से लागू किया जाए, विचार प्राप्त करने के लिए बस नंगे न्यूनतम, इसलिए मैंने एक स्पष्ट IEnumerable.GetEnumerator()पद्धति जैसी चीजों को छोड़ दिया ।


6
एक और उदाहरण जो मैं नए प्रोग्रामर के साथ उपयोग करता हूं वह एक Nodeवर्ग है a LinkedList। किसी को भी LinkedListपरवाह नहीं है कि कैसे Nodeलागू किया जाता है, जब तक वे सामग्री तक पहुंच सकते हैं। केवल एक इकाई जो सभी को ध्यान में रखती है वह है LinkedListवर्ग।
मगे Xy

3

तो एक नेस्टेड क्लास क्यों बनाएं?

मैं कुछ महत्वपूर्ण कारणों के बारे में सोच सकता हूं:

1. एनकैप्सुलेशन सक्षम करें

कई बार नेस्टेड क्लास कक्षा के कार्यान्वयन विवरण हैं। मुख्य वर्ग के उपयोगकर्ताओं को अपने अस्तित्व की परवाह नहीं करनी चाहिए। आपको मुख्य कोड के उपयोगकर्ताओं को अपना कोड बदलने की आवश्यकता के बिना उन्हें बदलने में सक्षम होना चाहिए।

2. नाम प्रदूषण से बचें

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

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

publid class LinkedList
{
   class Node { ... }
   // Use Node to implement the LinkedList class.
}

यदि आप Nodeउसी दायरे में जाने का निर्णय लेते हैं LinkedList, तो आपके पास होगा

public class LinkedListNode
{
}

public class LinkedList
{
  // Use LinkedListNode to implement the class
}

LinkedListNodeLinkedListवर्ग के बिना उपयोगी होने की संभावना नहीं है। यहां तक ​​कि अगर LinkedListकुछ कार्यों को प्रदान किया जाता है जो एक ऐसी LinkedListNodeवस्तु को पुन: प्राप्त करता है जो एक उपयोगकर्ता LinkedListउपयोग कर सकता है, तो यह अभी भी LinkedListNodeकेवल तब उपयोगी होता है जब LinkedListइसका उपयोग किया जाता है। उस कारण से, "नोड" वर्ग को एक सहकर्मी वर्ग बनाते LinkedListहुए युक्त गुंजाइश प्रदूषित कर रहा है।


0
  1. मैं संबंधित सहायक वर्गों के लिए सार्वजनिक नेस्टेड कक्षाओं का उपयोग करता हूं।

    public class MyRecord {
        // stuff
        public class Comparer : IComparer<MyRecord> {
        }
        public class EqualsComparer : IEqualsComparer<MyRecord> {
        }
    }
    MyRecord[] array;
    Arrays.sort(array, new MyRecord.Comparer());
  2. संबंधित विविधताओं के लिए उनका उपयोग करें।

    // Class that may or may not be mutable.
    public class MyRecord {
        protected string name;
        public virtual String Name { get => name; set => throw new InvalidOperation(); }
    
        public Mutable {
            public override String { get => name; set => name = value; }
        }
    }
    
    MyRecord mutableRecord = new MyRecord.Mutable();

कॉलर चुन सकता है कि कौन सा संस्करण किस समस्या के लिए उपयुक्त है। कभी-कभी एक कक्षा को पूरी तरह से एक पास में नहीं बनाया जा सकता है, और इसके लिए परिवर्तनशील संस्करण की आवश्यकता होती है। चक्रीय डेटा को हैंडल करते समय यह हमेशा सच होता है। Mutables को केवल-बाद में पढ़ने के लिए परिवर्तित किया जा सकता है।

  1. मैं उन्हें आंतरिक रिकॉर्ड के लिए उपयोग करता हूं

    public class MyClass {
        List<Line> lines = new List<Line>();
    
        public void AddUser( string name, string address ) => lines.Add(new Line { Name = name, Address = address });
    
        class Line { string Name; string Address; }
    }

0

नेस्टेड क्लास का उपयोग तब किया जा सकता है जब आप कक्षा के एक से अधिक बार बनाना चाहते हैं या जब भी आप उस प्रकार को अधिक उपलब्ध करना चाहते हैं।

नेस्टेड क्लास एन्कैप्सुलेशन बढ़ाता है और साथ ही यह अधिक पठनीय और बनाए रखने योग्य कोड को जन्म देगा।

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