सदस्यों को छिपाने के एकमात्र उद्देश्य के लिए स्पष्ट इंटरफ़ेस कार्यान्वयन का उपयोग करने के लिए अच्छे कारण क्या हैं?


11

C # की पेचीदगियों में मेरे एक अध्ययन के दौरान, मैं स्पष्ट इंटरफ़ेस कार्यान्वयन के विषय में एक दिलचस्प मार्ग से पार हुआ।

While this syntax is quite helpful when you need to resolve name clashes, you can use explicit interface implementation simply to hide more "advanced" members from the object level.

मेरी अनुभवहीन आँखों को माया-सरोकार की तरह लगता है के उपयोग की अनुमति देने object.method()या कास्टिंग की आवश्यकता के बीच अंतर ((Interface)object).method()। पाठ ने नोट किया कि यह वस्तु स्तर पर Intellisense से विधि को छिपाएगा, लेकिन आप ऐसा क्यों करना चाहते हैं यदि नाम संघर्ष से बचने के लिए यह आवश्यक नहीं था?


जवाबों:


12

ऐसी स्थिति की कल्पना करें जहां एक इंटरफ़ेस उन तरीकों को लागू करने के लिए एक वर्ग को मजबूर करता है जो वास्तव में वर्ग के हिस्से के रूप में समझ में नहीं आते हैं। यह अक्सर तब हो सकता है जब इंटरफेस विशेष रूप से बड़े होते हैं और इंटरफ़ेस अलगाव सिद्धांत का उल्लंघन करते हैं।

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


6
क्या यह सिर्फ मुझे है, या यह एक भयानक विचार की तरह लगता है?
केविन पेनो

5
@ केविन, ऐसा कैसे? कभी-कभी इंटरफ़ेस आपके नियंत्रण से बाहर है, और आपको इसका उपयोग करना होगा। एक शानदार इंटरफ़ेस के नुकसान को कम करना उचित लगता है।
क्रिस पिटमैन

1
+1 यह इंगित करने के लिए कि कई बार वास्तविक दुनिया चीजों को करने के सही तरीके के रास्ते में हो जाती है। @ केविन हाँ यह एक भयानक विचार है, लेकिन कभी-कभी आपके पास कोई विकल्प नहीं होता है और ढलान के साथ काम करना पड़ता है - बेहतर होगा कि इसे दूर छिपाएं और चीजों को ठीक से करने का एक मोहरा बनाएं जब आप वास्तव में इसे ठीक से नहीं कर सकते ।
वेन मोलिना

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

1
अत्यधिक इंटरफ़ेस पृथक्करण रचना और एकत्रीकरण के लिए एक बड़ी बाधा हो सकती है। उदाहरण के लिए, इस पर विचार करें कि IEnumerable<T>जिस पर दो अन्य लोगों की सहमति के रूप में व्यवहार किया जाता है, उसे लागू करना चाहता है । यदि IEnumerable<T>यह कहने के लिए कि क्या इसकी गणना ज्ञात थी, संभावित रूप से अनंत है, या न ही, यह पूछने के लिए एक विधि के साथ कि इसकी संख्या क्या है, एक वर्ग जो एकाधिक एकत्र करता है IEnumerable<T>और एक सहमति के रूप में व्यवहार करता है, कुशलता से इस मामले में अपनी गिनती रिपोर्ट कर सकता है समझाया संग्रह उनके मायने रखता था।
सुपरकैट

4

सबसे उपयोगी अनुप्रयोग मुझे कारखानों को लागू करने के साथ मिला है। कई मामलों में, यह उन वर्गों को बनाने के लिए उपयोगी है जो कारखाने के अंदर उत्परिवर्तनीय हैं लेकिन बाहरी कक्षाओं के लिए अपरिवर्तनीय हैं। यह आसानी से जावा में आंतरिक कक्षाओं का उपयोग करके, खेतों और उनके वासियों को निजी बनाने और केवल सार्वजनिक सदस्यों के रूप में गेटर्स को उजागर करने से लागू किया जा सकता है। हालाँकि C # में, मुझे एक ही चीज़ को प्राप्त करने के लिए स्पष्ट इंटरफेस का उपयोग करना पड़ा। मैं आगे समझाता हूँ:

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

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

उदाहरण:

public class Factory
{
    // factory method to create a hard-coded Mazda Tribute car.
    public static Car CreateCar()
    {
        Car car = new Car();

        // the Factory class can modify the model because it has access to
        // the private ICarSetters interface
        ((ICarSetters)car).model = "Mazda Tribute";

        return car;
    }

    // define a private interface containing the setters.
    private interface ICarSetters
    {
        // define the setter in the private interface
        string model { set; }
    }

    // This is the inner class. It has a member "model" that should not be modified
    // but clients, but should be modified by the factory.
    public class Car: ICarSetters
    {
        // explicitly implement the setter
        string ICarSetters.model { set; }

        // create a public getter
        public string model { get; }
    }
}

class Client
{
    public Client()
    {
        Factory.Car car = Factory.CreateCar();

        // can only read model because only the getter is public
        // and ICarSetters is private to Factory
        string model = car.model;
    }
}

यही कारण है कि मैं के लिए स्पष्ट इंटरफेस का उपयोग करेगा।


3

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

class Test 
{
    static void Main()

    {
        SampleClass sc = new SampleClass();
        IControl ctrl = (IControl)sc;
        ISurface srfc = (ISurface)sc;

        // The following lines all call the same method.
        sc.Paint();
        ctrl.Paint();
        srfc.Paint();
    }
}


interface IControl
{
    void Paint();
}
interface ISurface
{
    void Paint();
}
class SampleClass : IControl, ISurface
{
    // Both ISurface.Paint and IControl.Paint call this method. 
    public void Paint()
    {
        Console.WriteLine("Paint method in SampleClass");
    }
}

इसके विपरीत, उनमें से एक (या दोनों) का स्पष्ट कार्यान्वयन आपको प्रत्येक के लिए अलग व्यवहार निर्दिष्ट करने की अनुमति देता है।


1

स्पष्ट इंटरफेस तब काम आता है जब या तो किसी वस्तु के दो या दो से अधिक विशिष्ट रूप होते हैं।

उदाहरण के लिए, एक ऐसी वस्तु जो बाल वस्तुओं का एक संग्रह बनाए रखती है जिसे माता-पिता के साथ संवाद करने की आवश्यकता होती है।

कुछ क्रियाएं हैं जो हम केवल बाहरी कॉल करने वालों के लिए सुलभ चाहते हैं और कुछ क्रियाएं हम केवल बाल वस्तुओं के लिए सुलभ चाहते हैं।

स्पष्ट इंटरफेस इस विभाजन को सुनिश्चित करने में मदद करते हैं।

    static void Main(string[] args)
    {
        var parent = new Parent();
        parent.DoExternalStuff();
    }

    interface IExternal {
        void DoExternalStuff();
    }

    interface IInternal {
        void DoInternalStuff();
    }

    class Parent : IExternal, IInternal
    {
        public Parent()
        {
            var child = new Child(this);
        }

        public void DoExternalStuff()
        {
           // do something exciting here for external callers
        }

        void IInternal.DoInternalStuff()
        {
            // do something exciting here for internal callers
        }
    }

    class Child
    {
        public Child(IInternal parent)
        {
            parent.DoInternalStuff();
        }
    }

0

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

ऐसा करने के बजाए आप ऐसा क्यों करेंगे, एक दूसरा "उन्नत सुविधाएँ इंटरफ़ेस" मुझे नहीं पता।


0

कोड आमतौर पर लिखे जाने से ज्यादा पढ़ा जाता है और मैं कोड लिखने के लिए केवल Intellisense का उपयोग करता हूं। मैं कोड को एक विशेष तरीके से नहीं लिखूंगा सिर्फ इंटेलीसेंस नाइसर बनाने के लिए।

मैं विशेष रूप से नहीं देखता कि कैसे

((इंटरफ़ेस) ऑब्जेक्ट) .method () object.method () की तुलना में अधिक पठनीय है।

यदि मेरे पास किसी विशेष वस्तु पर बहुत सारे तरीके हैं, तो मैं सवाल कर सकता हूं कि क्या इसकी कोई ईश्वर वस्तु है या नहीं और वास्तव में इसे कई सरल वस्तुओं में तोड़ दिया जाना चाहिए।

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