language agnostic "इंटरफ़ेस पर प्रोग्राम" का क्या अर्थ है?




language-agnostic oop (24)

एक इंटरफेस के लिए प्रोग्रामिंग में अमूर्त इंटरफेस के साथ बिल्कुल कुछ नहीं है जैसे कि हम जावा या .NET में देखते हैं। यह एक ओओपी अवधारणा भी नहीं है।

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

संपादित करें: और डेटाबेस के साथ इसका मतलब प्रत्यक्ष तालिका पहुंच के बजाय दृश्यों और संग्रहीत प्रक्रियाओं का उपयोग करना है।

मैंने देखा है कि यह कुछ बार उल्लेख किया गया है और मैं इसका अर्थ स्पष्ट नहीं हूं। आप कब और क्यों करेंगे?

मुझे पता है कि इंटरफेस क्या करते हैं, लेकिन तथ्य यह है कि मैं इस पर स्पष्ट नहीं हूं, मुझे लगता है कि मैं उन्हें सही तरीके से उपयोग करने से चूक रहा हूं।

क्या यह ऐसा है यदि आप करना चाहते थे:

IInterface classRef = new ObjectWhatever()

आप किसी भी वर्ग का उपयोग कर सकते हैं जो IInterface लागू IInterface ? आपको ऐसा करने की आवश्यकता कब होगी? एकमात्र चीज जो मैं सोच सकता हूं वह यह है कि यदि आपके पास कोई तरीका है और आप अनिश्चित हैं कि IInterface कार्यान्वित करने के लिए कौन सी वस्तु पारित की IInterface । मैं नहीं सोच सकता कि आपको कितनी बार ऐसा करने की आवश्यकता होगी ... (इसके अलावा, आप एक ऐसी विधि कैसे लिख सकते हैं जो किसी ऑब्जेक्ट को लेती है जो इंटरफ़ेस लागू करती है? क्या यह संभव है?)

क्षमा करें अगर मैं पूरी तरह से बिंदु चूक गया।


वहां बहुत सारी स्पष्टीकरण है, लेकिन इसे और भी आसान बनाने के लिए। उदाहरण के लिए एक List ले लो। कोई एक सूची को इस प्रकार कार्यान्वित कर सकता है:

  1. एक आंतरिक सरणी
  2. एक लिंक्ड सूची
  3. अन्य कार्यान्वयन

एक इंटरफेस के निर्माण के द्वारा, एक List कहें। आप केवल सूची की परिभाषा के रूप में कोड या वास्तविकता में किस List मतलब है।

आप किसी भी प्रकार के कार्यान्वयन का उपयोग आंतरिक रूप से एक array कार्यान्वयन कह सकते हैं। लेकिन मान लीजिए कि आप कुछ कारणों से कार्यान्वयन को बदलना चाहते हैं, बग या प्रदर्शन कहें। फिर आपको केवल List<String> ls = new ArrayList<String>() List<String> ls = new LinkedList<String>() बदलना होगा।

कोड में कहीं और नहीं, आपको कुछ और बदलना होगा; क्योंकि बाकी सब कुछ List परिभाषा पर बनाया गया था।


It can be advantageous to program to interfaces, even when we are not depending on abstractions.

Programming to interfaces forces us to use a contextually appropriate subset of an object. That helps because it:

  1. prevents us from doing contextually inappropriate things, and
  2. lets us safely change the implementation in the future.

For example, consider a Person class that implements the Friend and the Employee interface.

class Person implements AbstractEmployee, AbstractFriend {

}

In the context of the person's birthday, we program to the Friend interface, to prevent treating the person like an Employee .

function party() {
    const friend: Friend = new Person("Kathryn");
    friend.HaveFun();
}

In the context of the person's work, we program to the Employee interface, to prevent blurring workplace boundaries.

function workplace() {
    const employee: Employee = new Person("Kathryn");
    employee.DoWork();
}

महान। We have behaved appropriately in different contexts, and our software is working well.

Far into the future, if our business changes to work with dogs, we can change the software fairly easily. First, we create Dog class that implements both Friend and Employee . Then, we safely change new Person() to new Dog() . Even if both functions have thousands of lines of code, that simple edit will work because we know the following are true:

  1. Function party uses only the Friend subset of Person .
  2. Function workplace uses only the Employee subset of Person .
  3. Class Dog implements both the Friend and Employee interfaces.

On the other hand, if either party or workplace were to have programmed against Person , there would be a risk of both having Person -specific code. Changing from Person to Dog would require us to comb through the code to extirpate any Person -specific code that Dog does not support.

The moral : programming to interfaces helps our code to behave appropriately and to be ready for change. It also prepares our code to depend on abstractions, which brings even more advantages.


C++ explanation.

Think of an interface as your classes public methods.

You then could create a template that 'depends' on these public methods in order to carry out it's own function (it makes function calls defined in the classes public interface). Lets say this template is a container, like a Vector class, and the interface it depends on is a search algorithm.

Any algorithm class that defines the functions/interface Vector makes calls to will satisfy the 'contract' (as someone explained in the original reply). The algorithms don't even need to be of the same base class; the only requirement is that the functions/methods that the Vector depends on (interface) is defined in your algorithm.

The point of all of this is that you could supply any different search algorithm/class just as long as it supplied the interface that Vector depends on (bubble search, sequential search, quick search).

You might also want to design other containers (lists, queues) that would harness the same search algorithm as Vector by having them fulfill the interface/contract that your search algorithms depends on.

This saves time (OOP principle 'code reuse') as you are able to write an algorithm once instead of again and again and again specific to every new object you create without over-complicating the issue with an overgrown inheritance tree.

As for 'missing out' on how things operate; big-time (at least in C++), as this is how most of the Standard TEMPLATE Library's framework operates.

Of course when using inheritance and abstract classes the methodology of programming to an interface changes; but the principle is the same, your public functions/methods are your classes interface.

This is a huge topic and one of the the cornerstone principles of Design Patterns.


कल्पना कीजिए कि आपके पास 'ज़ेबरा' नामक एक उत्पाद है जिसे प्लगइन द्वारा बढ़ाया जा सकता है। यह कुछ निर्देशिका में डीएलएल की खोज करके प्लगइन्स पाता है। यह उन सभी डीएलएल को लोड करता है और IZebraPlugin लागू करने वाले किसी भी वर्ग को खोजने के लिए प्रतिबिंब का उपयोग करता है, और उसके बाद प्लगइन के साथ संवाद करने के लिए उस इंटरफ़ेस के तरीकों को कॉल करता है।

यह किसी भी विशिष्ट प्लगइन वर्ग से पूरी तरह से स्वतंत्र बनाता है - यह परवाह नहीं करता कि कक्षाएं क्या हैं। यह केवल परवाह करता है कि वे इंटरफेस विनिर्देश को पूरा करते हैं।

इंटरफेस इस तरह की विस्तारशीलता के बिंदु को परिभाषित करने का एक तरीका है। Code that talks to an interface is more loosely coupled - in fact it is not coupled at all to any other specific code. It can inter-operate with plugins written years later by people who have never met the original developer.

You could instead use a base class with virtual functions - all plugins would be derived from the base class. But this is much more limiting because a class can only have one base class, whereas it can implement any number of interfaces.


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


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

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

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

मैंने इन घटकों के लिए एक सरल इंटरफ़ेस परिभाषित किया है और सभी बेस क्लास इस इंटरफ़ेस से बात करते हैं। अब जब मैं कुछ बदलता हूं, तो यह हर जगह 'बस काम करता है' और मेरे पास कोई कोड डुप्लिकेशन नहीं है।


Also I see a lot of good and explanatory answers here, so I want to give my point of view here, including some extra information what I noticed when using this method.

Unit testing

For the last two years, I have written a hobby project and I did not write unit tests for it. After writing about 50K lines I found out it would be really necessary to write unit tests. I did not use interfaces (or very sparingly) ... and when I made my first unit test, I found out it was complicated. Why?

Because I had to make a lot of class instances, used for input as class variables and/or parameters. So the tests look more like integration tests (having to make a complete 'framework' of classes since all was tied together).

Fear of interfaces So I decided to use interfaces. My fear was that I had to implement all functionality everywhere (in all used classes) multiple times. In some way this is true, however, by using inheritance it can be reduced a lot.

Combination of interfaces and inheritance I found out the combination is very good to be used. I give a very simple example.

public interface IPricable
{
    int Price { get; }
}

public interface ICar : IPricable

public abstract class Article
{
    public int Price { get { return ... } }
}

public class Car : Article, ICar
{
    // Price does not need to be defined here
}

This way copying code is not necessary, while still having the benefit of using a car as interface (ICar).


In simple terms... If I'm writing a new class Swimmer to add the functionality swim() and need to use an object of class say Dog, and this Dog class implements interface Animal which declares swim()[To better understand...you may draw a diagram as to what I am talking about]. At the top of the hierarchy(Animal) it's very abstract while at the bottom (Dog) it's very concrete. The way I think about "programming to interfaces" is that, as I write Swimmer class, I want to write my code against the interface that's as far up that hierarchy which in this case is Animal object. An interface is free from implementation details and thus makes your code loosely-coupled. The implementation details can be changed with time, however it would not affect the remaining code since all you are interacting is with the interface and not the implementation. You don't care what the implementation is like...all you know is that there will be a class that would implement the interface.


I don't retain interface s are the most important thing in a language: it's more commonly used the class inheriting. But anyway they are important!
For example (this is Java code, but it can simply adapted to C# or many other languages):

interface Convertable<T> {

    T convert();
}

public class NumerableText implements Convertable<Integer> {

    private String text = "";

    public NumerableText() { }

    public NumerableText(String text) {
        this.text = text;
    }

    public String getText() {
        return this.text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public Integer convert() {
        return this.text.hashCode();
    }
}

public class NumerableTextArray implements Convertable<Integer> {

    private String[] textArray = "";

    public NumerableTextArray() { }

    public NumerableTextArray(String[] textArray) {
        this.textArray = textArray;
    }

    public String[] getTextArray() {
        return this.textArray;
    }

    public void setTextArray(String[] text) {
        this.textArray = textArray;
    }

    public Integer convert() {
        Integer value = 0;
        for (String text : textArray)
            value += text.hashCode();
        return value;
    }
}

public class Foo {

    public static void main() {
        Convertable<Integer> num1 = new NumerableText("hello");
        Convertable<Integer> num2 = new NumerableTextArray(new String[] { "test n°1", "test n°2" });
        System.out.println(String.valueOf(num1.convert()));
        System.out.println(String.valueOf(num2.convert()));
        //Here are you two numbers generated from two classes of different type, but both with the method convert(), which allows you to get that number.
    }
}

आपको नियंत्रण में उलझन में देखना चाहिए:

ऐसे परिदृश्य में, आप इसे नहीं लिखेंगे:

IInterface classRef = new ObjectWhatever();

आप इस तरह कुछ लिखेंगे:

IInterface classRef = container.Resolve<IInterface>();

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

यदि हम तालिका से आईओसी छोड़ते हैं, तो आप कोड लिख सकते हैं जो जानता है कि यह किसी ऑब्जेक्ट से बात कर सकता है जो कुछ विशिष्ट करता है , लेकिन किस प्रकार की वस्तु नहीं है या यह कैसे करता है।

पैरामीटर पारित करते समय यह आसान होगा।

आपके संश्लेषित प्रश्न के लिए "इसके अलावा, आप एक ऐसी विधि कैसे लिख सकते हैं जो किसी ऑब्जेक्ट को लेता है जो इंटरफ़ेस लागू करता है? क्या यह संभव है?", सी # में आप पैरामीटर प्रकार के लिए इंटरफ़ेस प्रकार का उपयोग करेंगे, जैसे:

public void DoSomethingToAnObject(IInterface whatever) { ... }

यह सही है "किसी ऑब्जेक्ट से बात करें जो कुछ विशिष्ट करता है।" ऊपर परिभाषित विधि जानता है कि ऑब्जेक्ट से क्या अपेक्षा की जा सकती है, यह IInterface में सबकुछ लागू करता है, लेकिन यह परवाह नहीं करता कि यह किस प्रकार की ऑब्जेक्ट है, केवल यह कि यह अनुबंध का पालन करता है, जो एक इंटरफ़ेस है।

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

यह इंटरफेस की सुंदरता है। आप कोड का एक टुकड़ा लिख ​​सकते हैं, जो जानता है कि यह वस्तुओं को पास कर देगा कि इससे कुछ व्यवहार की उम्मीद हो सकती है। यह परवाह नहीं करता है कि यह किस तरह की वस्तु है, केवल यह कि वह आवश्यक व्यवहार का समर्थन करता है।

मुझे आपको एक ठोस उदाहरण दें।

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

अब, चूंकि नियंत्रण पूर्व परिभाषित वर्गों से प्राप्त होता है, जिन पर हमारा कोई नियंत्रण नहीं होता है, हम तीन चीजों में से एक कर सकते हैं:

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

तो हमने एनआर किया। 3. हमारे सभी नियंत्रण ILocalizable लागू करते हैं, जो एक इंटरफ़ेस है जो हमें एक विधि देता है, अनुवाद पाठ / नियमों के कंटेनर में "स्वयं" का अनुवाद करने की क्षमता देता है। इस प्रकार, फॉर्म को यह जानने की आवश्यकता नहीं है कि इसे किस प्रकार का नियंत्रण मिला है, केवल यह कि यह विशिष्ट इंटरफ़ेस लागू करता है, और जानता है कि एक तरीका है जहां यह नियंत्रण को स्थानीयकृत करने के लिए कह सकता है।


Program to an interface allows to change implementation of contract defined by interface seamlessly. It allows loose coupling between contract and specific implementations.

IInterface classRef = new ObjectWhatever()

You could use any class that implements IInterface? When would you need to do that?

Have a look at this SE question for good example.

Why should the interface for a Java class be preferred?

does using an Interface hit performance?

if so how much?

हाँ। It will have slight performance overhead in sub-seconds. But if your application has requirement to change the implementation of interface dynamically, don't worry about performance impact.

how can you avoid it without having to maintain two bits of code?

Don't try to avoid multiple implementations of interface if your application need them. In absence of tight coupling of interface with one specific implementation, you may have to deploy the patch to change one implementation to other implementation.

One good use case: Implementation of Strategy pattern:

Real World Example of the Strategy Pattern


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


Let's start out with some definitions first:

Interface n. The set of all signatures defined by an object's operations is called the interface to the object

Type n. A particular interface

A simple example of an interface as defined above would be all the PDO object methods such as query() , commit() , close() etc., as a whole, not separately. These methods, ie its interface define the complete set of messages, requests that can be sent to the object.

A type as defined above is a particular interface. I will use the made-up shape interface to demonstrate: draw() , getArea() , getPerimeter() etc..

If an object is of the Database type we mean that it accepts messages/requests of the database interface, query() , commit() etc.. Objects can be of many types. You can have a database object be of the shape type as long as it implements its interface, in which case this would be sub-typing .

Many objects can be of many different interfaces/types and implement that interface differently. This allows us to substitute objects, letting us choose which one to use. Also known as polymorphism.

The client will only be aware of the interface and not the implementation.

So in essence programming to an interface would involve making some type of abstract class such as Shape with the interface only specified ie draw() , getCoordinates() , getArea() etc.. And then have different concrete classes implement those interfaces such as a Circle class, Square class, Triangle class. Hence program to an interface not an implementation.


इंटरफेस के लिए प्रोग्रामिंग कमाल है, यह ढीला युग्मन को बढ़ावा देता है। जैसा कि @lassevk ने उल्लेख किया है, नियंत्रण का उलटा इस का एक बड़ा उपयोग है।

इसके अलावा, ठोस प्रिंसिपल में देखोयहां एक वीडियो श्रृंखला है

यह एक हार्ड कोड (दृढ़ता से युग्मित उदाहरण) के माध्यम से जाता है, फिर इंटरफेस को देखता है, अंततः आईओसी / डीआई उपकरण (एन इंजेक्ट) में प्रगति करता है।


इंटरफ़ेस को कोड नहीं कार्यान्वयन जावा के साथ कुछ भी नहीं है, न ही इसके इंटरफेस निर्माण।

इस अवधारणा को चार पुस्तकों के पैटर्न / गिरोह में प्रमुखता में लाया गया था, लेकिन इससे पहले शायद सबसे अच्छा था। जावा अस्तित्व से पहले अवधारणा निश्चित रूप से अस्तित्व में थी।

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

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

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

इस विचार को हिलाएं कि जावा इंटरफेस के पास 'इंटरफ़ेस के लिए कार्यक्रम, कार्यान्वयन नहीं' की अवधारणा के साथ क्या करना है। वे अवधारणा को लागू करने में मदद कर सकते हैं, लेकिन वे अवधारणा नहीं हैं।


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

उदाहरण के लिए, मैं एक आंदोलन इंटरफेस हो सकता है। एक तरीका जो कुछ 'चाल' बनाता है और किसी ऑब्जेक्ट (व्यक्ति, कार, बिल्ली) जो आंदोलन इंटरफ़ेस को लागू करता है उसे पारित किया जा सकता है और आगे बढ़ने के लिए कहा जा सकता है। विधि के बिना प्रत्येक वर्ग के वर्ग को जानने के लिए यह है।


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

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

उदाहरण के लिए - कहें कि आपके पास सिम गेम है और निम्न वर्ग हैं:

 class HouseFly inherits Insect {
   void FlyAroundYourHead(){}
   void LandOnThings(){}
 }

 class Telemarketer inherits Person {
   void CallDuringDinner(){}
   void ContinueTalkingWhenYouSayNo(){}
 }

जाहिर है, प्रत्यक्ष विरासत के मामले में इन दो वस्तुओं में कुछ भी सामान्य नहीं है। लेकिन, आप कह सकते हैं कि वे दोनों परेशान हैं।

आइए मान लें कि हमारे गेम में कुछ प्रकार की यादृच्छिक चीज है जो गेम प्लेयर को डिनर खाने पर परेशान करती है। यह HouseFly या Telemarketer या दोनों हो सकता है - लेकिन आप एक समारोह के साथ दोनों की अनुमति कैसे देते हैं? और आप एक अलग तरीके से "अपनी परेशान चीज" करने के लिए प्रत्येक अलग-अलग प्रकार की वस्तु से कैसे पूछते हैं?

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

 interface IPest {
    void BeAnnoying();
 }

 class HouseFly inherits Insect implements IPest {
   void FlyAroundYourHead(){}
   void LandOnThings(){}

   void BeAnnoying() {
     FlyAroundYourHead();
     LandOnThings();
   }
 }

 class Telemarketer inherits Person implements IPest {
   void CallDuringDinner(){}
   void ContinueTalkingWhenYouSayNo(){}

   void BeAnnoying() {
      CallDuringDinner();
      ContinueTalkingWhenYouSayNo();
   }
 }

अब हमारे पास दो वर्ग हैं जो प्रत्येक अपने तरीके से परेशान हो सकते हैं। और उन्हें एक ही बेस क्लास से प्राप्त करने और सामान्य अंतर्निहित विशेषताओं को साझा करने की आवश्यकता नहीं है - उन्हें केवल IPest के अनुबंध को पूरा करने की IPest - यह अनुबंध सरल है। आपको बस BeAnnoying । इस संबंध में, हम निम्नलिखित मॉडल कर सकते हैं:

 class DiningRoom {

   DiningRoom(Person[] diningPeople, IPest[] pests) { ... }

   void ServeDinner() {
     when diningPeople are eating,

       foreach pest in pests
         pest.BeAnnoying();
   }
 }

यहां हमारे पास एक डाइनिंग रूम है जो कई डिनरों और कई कीटों को स्वीकार करता है - इंटरफ़ेस के उपयोग को नोट करें। इसका मतलब है कि हमारी छोटी दुनिया में, pests सरणी का एक सदस्य वास्तव में Telemarketer ऑब्जेक्ट या HouseFly ऑब्जेक्ट हो सकता है।

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

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


Q: - ... "You could use any class that implements interface?"
A: - Yes.

Q: -... "When would you need to do that?"
A: - Each time you need a class(es) that implements interface(s).

Note: we couldn't instantiate an interface not implemented by a class - True.

  • क्यूं कर?
  • because interface has only methods prototypes, not definitions (just functions names, not their logic)

AnIntf anInst = new Aclass();
// we could do this only if Aclass implements AnIntf.
// anInst will have Aclass reference.

ध्यान दें:
Now we could understand what happend if Bclass and Cclass implements same Dintf.

Dintf bInst = new Bclass();  
// now we could call all Dintf functions implemented (defined) in Bclass.

Dintf cInst = new Cclass();  
// now we could call all Dintf functions implemented (defined) in Cclass.

हमारे पास क्या है:
same interface prototypes (functions names in interface), and call different implementations.

Bibliography:
Prototypes - wikipedia


ऐसा लगता है जैसे आप समझते हैं कि इंटरफेस कैसे काम करते हैं लेकिन इनका उपयोग करने के बारे में अनिश्चित हैं और वे क्या फायदे देते हैं। यहां कुछ उदाहरण दिए गए हैं जब इंटरफ़ेस समझ में आएगा:

// if I want to add search capabilities to my application and support multiple search
// engines such as google, yahoo, live, etc.

interface ISearchProvider
{
    string Search(string keywords);
}

तो मैं GoogleSearchProvider, YahooSearchProvider, LiveSearchProvider आदि बना सकता था।

// if I want to support multiple downloads using different protocols
// HTTP, HTTPS, FTP, FTPS, etc.
interface IUrlDownload
{
    void Download(string url)
}

// how about an image loader for different kinds of images JPG, GIF, PNG, etc.
interface IImageLoader
{
    Bitmap LoadImage(string filename)
}

फिर JpegImageLoader, GifImageLoader, PngImageLoader, आदि बनाएं।

अधिकांश ऐड-इन्स और प्लगइन sytems इंटरफेस से काम करते हैं।

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

interface IZipCodeRepository
{
    IList<ZipCode> GetZipCodes(string state);
}

तो मैं एक XMLZipCodeRepository, SQLZipCodeRepository, CSVZipCodeRepository, आदि बना सकता हूं। मेरे वेब अनुप्रयोगों के लिए मैं अक्सर एक्सएमएल रिपॉजिटरीज बना देता हूं ताकि मैं एसक्यूएल डाटाबेस तैयार होने से पहले कुछ प्राप्त कर सकूं। एक बार डेटाबेस तैयार हो जाने पर मैं XML संस्करण को प्रतिस्थापित करने के लिए एक SQLRepository लिखता हूं। मेरा शेष कोड अपरिवर्तित बनी हुई है क्योंकि यह इंटरफेस से इतनी दूर चला जाता है।

तरीके इंटरफ़ेस स्वीकार कर सकते हैं जैसे कि:

PrintZipCodes(IZipCodeRepository zipCodeRepository, string state)
{
    foreach (ZipCode zipCode in zipCodeRepository.GetZipCodes(state))
    {
        Console.WriteLine(zipCode.ToString());
    }
}

In Java these concrete classes all implement the CharSequence interface:

CharBuffer, String, StringBuffer, StringBuilder

These concrete classes do not have a common parent class other than Object, so there is nothing that relates them, other than the fact they each have something to do with arrays of characters, representing such, or manipulating such. For instance, the characters of String cannot be changed once a String object is instantiated, whereas the characters of StringBuffer or StringBuilder can be edited.

Yet each one of these classes is capable of suitably implementing the CharSequence interface methods:

char charAt(int index)
int length()
CharSequence subSequence(int start, int end)
String toString()

In some cases Java class library classes that used to accept String have been revised to now accept the CharSequence interface. So if you have an instance of StringBuilder, instead of extracting a String object (which means instantiating a new object instance), can instead just pass the StringBuilder itself as it implements the CharSequence interface.

The Appendable interface that some classes implement has much the same kind of benefit for any situation where characters can be appended to an instance of the underlying concrete class object instance. All of these concrete classes implement the Appendable interface:

BufferedWriter, CharArrayWriter, CharBuffer, FileWriter, FilterWriter, LogStream, OutputStreamWriter, PipedWriter, PrintStream, PrintWriter, StringBuffer, StringBuilder, StringWriter, Writer


एक इंटरफेस के लिए प्रोग्रामिंग कह रही है, "मुझे इस कार्यक्षमता की आवश्यकता है और मुझे परवाह नहीं है कि यह कहां से आता है।"

(जावा में) पर विचार करें, List इंटरफ़ेस बनाम List इंटरफेस और LinkedList कंक्रीट कक्षाओं। अगर मुझे इस बात की परवाह है कि मेरे पास एक डेटा संरचना है जिसमें एकाधिक डेटा आइटम हैं जिन्हें मुझे पुनरावृत्ति के माध्यम से एक्सेस करना चाहिए, तो मैं एक List (और वह 99% समय) चुनता हूं। अगर मुझे पता है कि मुझे सूची के किसी भी छोर से लगातार समय डालने / हटाने की आवश्यकता है, तो मैं LinkedList कंक्रीट कार्यान्वयन (या अधिक संभावना है, Queue इंटरफ़ेस का उपयोग कर सकता हूं) चुन सकता हूं। अगर मुझे पता है कि मुझे इंडेक्स द्वारा यादृच्छिक पहुंच की आवश्यकता है, तो मैं ArrayList कंक्रीट क्लास ArrayList


जब आप एक उड़ान बुकिंग प्रणाली प्रोग्राम करते हैं तो यह स्पष्ट करने के लिए यहां एक सरल उदाहरण दिया गया है।

//This interface is very flexible and abstract
    addPassenger(Plane seat, Ticket ticket); 

//Boeing is implementation of Plane
    addPassenger(Boeing747 seat, EconomyTicket ticket); 
    addPassenger(Cessna, BusinessClass ticket);


    addPassenger(J15, E87687); 

Interface is like contract where you want your implementation class to implement methods written in contract(Interface).Since java does not provide multiple inheritance,programming to interface is a good way to achieve purpose of multiple inheritance.If you have a class A that is already extending some other class B but you want that class A should also follow certain guidelines or implement certain contract then you can do so by programming to interface strategy.





interface