PHP में इंटरफेस की बात क्या है?


224

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

सार कक्षाएं आपको विधि के साथ कोड जोड़ने के साथ, एक ही काम करने की अनुमति देती हैं।

अब यदि आप अमूर्त वर्गों के साथ एक ही लक्ष्य प्राप्त कर सकते हैं, तो हमें इंटरफेस की अवधारणा की भी आवश्यकता क्यों है?

मुझे बताया गया है कि इसे C ++ से जावा तक OO सिद्धांत के साथ करना है, जो कि PHP का OO सामान है। क्या अवधारणा जावा में उपयोगी है लेकिन PHP में नहीं है? क्या यह सिर्फ एक तरीका है जो प्लेसहोल्डर्स को एब्सट्रैक्ट क्लास में रखने से रोकता है? क्या मैं कुछ भूल रहा हूँ?


4
आपको इसे पढ़ना होगा: stackoverflow.com/a/384067/14673
Luc M

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

जवाबों:


142

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

इंटरफेस एक समझौता है। मल्टीपल इनहेरिटेंस के साथ अधिकांश समस्याएं अमूर्त आधार वर्गों पर लागू नहीं होती हैं, इसलिए इन दिनों अधिकांश आधुनिक भाषाएं कई विरासत को अक्षम कर देती हैं, फिर भी एब्सट्रैक्ट बेस क्लास इंटरफेस को कॉल करती हैं और एक क्लास को उनमें से कई के रूप में "लागू करने" की अनुमति देती हैं।


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

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

15
यही कारण है कि इंटरफेस बिल्कुल नहीं हैं। यह कई विरासतों पर समझौता नहीं है, यह वस्तुओं को लागू करने के लिए एक वैचारिक और सार अनुबंध बनाने और अन्य वस्तुओं / उपभोग करने के तरीकों के बारे में है। इंटरफेस बहुरूपता के लिए एक उपकरण है, और प्रत्यक्ष विरासत के लिए नहीं।
मडारा का भूत

123

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


इससे मुझे थोड़ा समझ में आया। यह नाम स्थान के साथ है - इसलिए साझा कोड का उपयोग करना आसान है और बिना किसी संघर्ष के। यह आसान है जब दो लोग एक ही आधार पर कक्षाएं बनाते हैं, है ना?
RedClover

क्या हमें 'इंटरफेस' की सामान्य अवधारणा को PHP जैसी भाषा में ठोस इंटरफेस से अलग करने की आवश्यकता नहीं है? उदाहरण के लिए, किसी भी फ़ंक्शन में एक "इंटरफ़ेस" होता है जो परिभाषित करता है कि आप इसका उपयोग कैसे करते हैं और इसके कार्यान्वयन को छिपाते हैं। तो उस तरह के "कॉन्ट्रैक्चुअल" इंटरफ़ेस के लिए एक विशेष भाषा की आवश्यकता नहीं होती है। इसलिए भाषा की सुविधा कुछ और (या इसके अतिरिक्त कुछ) के लिए होनी चाहिए,
UuDdLrLrSs

70

यदि पहले से ही अमूर्त वर्ग हैं, तो आपको इंटरफ़ेस की आवश्यकता क्यों होगी? एकाधिक वंशानुक्रम को रोकने के लिए (कई ज्ञात समस्याओं का कारण बन सकता है)।

ऐसी समस्याओं में से एक:

"डायमंड प्रॉब्लम" (कभी-कभी "मौत का घातक हीरा" के रूप में जाना जाता है) एक अस्पष्टता है जो तब उत्पन्न होती है जब ए और क्लास डी से विरासत में दो वर्ग बी और सी दोनों से विरासत में मिलते हैं और अगर ए में कोई विधि है। B और C ने ओवरराइड किया है, और D ने इसे ओवरराइड नहीं किया है, तो D का कौन सा वर्जन इनहेरिट करता है: B का, या C का?

स्रोत: https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem

क्यों / कब एक इंटरफ़ेस का उपयोग करने के लिए? एक उदाहरण ... दुनिया की सभी कारों में एक ही इंटरफ़ेस (तरीके) हैं ... AccelerationPedalIsOnTheRight(), BrakePedalISOnTheLeft()। कल्पना करें कि प्रत्येक कार ब्रांड में ये "तरीके" दूसरे ब्रांड से अलग होंगे। बीएमडब्ल्यू में दाईं ओर ब्रेक होगा, और होंडा व्हील के बाईं ओर ब्रेक होगा। लोगों को सीखना होगा कि ये "तरीके" हर बार कैसे काम करते हैं जब वे एक अलग ब्रांड की कार खरीदेंगे। यही कारण है कि कई "स्थानों" में समान इंटरफ़ेस रखना एक अच्छा विचार है।

आपके लिए एक इंटरफ़ेस क्या करता है (कोई किसी का उपयोग क्यों करेगा)? एक इंटरफ़ेस आपको "गलतियाँ" करने से रोकता है (यह आपको विश्वास दिलाता है कि सभी वर्ग जो एक विशिष्ट इंटरफ़ेस को लागू करते हैं, सभी में वही विधियाँ होंगी जो इंटरफ़ेस में हैं)।

// Methods inside this interface must be implemented in all classes which implement this interface.
interface IPersonService
{   
    public function Create($personObject);
}

class MySqlPerson implements IPersonService
{
    public function Create($personObject)
    {
        // Create a new person in MySql database.
    }
}

class MongoPerson implements IPersonService
{
    public function Create($personObject)
    {
        // Mongo database creates a new person differently then MySQL does. But the code outside of this method doesn't care how a person will be added to the database, all it has to know is that the method Create() has 1 parameter (the person object).
    }
}

इस तरह, Create()विधि हमेशा उसी तरह से उपयोग की जाएगी। इससे कोई फर्क नहीं पड़ता कि हम MySqlPersonक्लास या क्लास का उपयोग कर रहे हैं MongoPerson। जिस तरह से हम एक विधि का उपयोग कर रहे हैं वह उसी तरह रहता है (इंटरफ़ेस समान रहता है)।

उदाहरण के लिए, इसका उपयोग इस तरह किया जाएगा (हमारे कोड में हर जगह):

new MySqlPerson()->Create($personObject);
new MongoPerson()->Create($personObject);

इस तरह, ऐसा कुछ नहीं हो सकता है:

new MySqlPerson()->Create($personObject)
new MongoPerson()->Create($personsName, $personsAge);

एक इंटरफ़ेस को याद रखना और कई अलग-अलग लोगों की तुलना में हर जगह एक ही उपयोग करना बहुत आसान है।

इस तरह, Create()विधि के अंदर "बाहर" कोड को प्रभावित किए बिना, विभिन्न वर्गों के लिए अलग-अलग हो सकता है, जो इस पद्धति को कॉल करता है। सभी बाहरी कोड को जानना होगा कि विधि Create()में 1 पैरामीटर ( $personObject) है, क्योंकि इस तरह से बाहरी कोड विधि का उपयोग / कॉल करेगा। बाहरी कोड को इस बात की परवाह नहीं है कि विधि के अंदर क्या हो रहा है; इसे केवल यह जानना है कि इसका उपयोग कैसे करें / कॉल करें।

आप इसे एक इंटरफ़ेस के बिना भी कर सकते हैं, लेकिन यदि आप एक इंटरफ़ेस का उपयोग करते हैं, तो यह "सुरक्षित" है (क्योंकि यह आपको गलतियाँ करने से रोकता है)। इंटरफ़ेस आपको आश्वासन देता है कि इस पद्धति Create()में इंटरफ़ेस को लागू करने वाले सभी वर्गों में एक ही हस्ताक्षर (समान प्रकार और कई मापदंडों) होंगे। इस तरह आप सुनिश्चित कर सकते हैं कि कोई भी वर्ग जो IPersonServiceइंटरफ़ेस को लागू करता है, उसके पास विधि Create()(इस उदाहरण में) होगी और उसे $personObjectकॉल / उपयोग करने के लिए केवल 1 पैरामीटर ( ) की आवश्यकता होगी ।

एक वर्ग जो एक इंटरफ़ेस को लागू करता है, उसे सभी तरीकों को लागू करना चाहिए, जो इंटरफ़ेस करता है / है।

मुझे आशा है कि मैंने खुद को बहुत अधिक नहीं दोहराया।


कार पेडल के साथ वास्तव में अच्छा सादृश्य!
जेम्स

24

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

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

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

इसके विपरीत, मैं एक ऐसी वस्तु भी बना सकता हूं जो खाता से विस्तारित नहीं होती है, एक उपयोगकर्ता सार वर्ग कहता है, और फिर भी सूची और संपादन योग्य लागू करता है, लेकिन संस्करण योग्य नहीं है, जो यहां समझ में नहीं आता है।

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

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


यह यहीं है। Rigidly देवों को लागू करने या उन्हें अधिलेखित किए बिना अपने तरीकों का उपयोग करने के लिए लागू करता है
निक

21

इंटरफेस अनिवार्य रूप से एक खाका है जो आप बना सकते हैं। वे परिभाषित करते हैं कि कक्षा में क्या विधियाँ होनी चाहिए , लेकिन आप उन सीमाओं के बाहर अतिरिक्त तरीके बना सकते हैं।

मुझे यकीन नहीं है कि आप तरीकों से कोड जोड़ने में सक्षम नहीं होने का क्या मतलब है - क्योंकि आप कर सकते हैं। क्या आप इंटरफ़ेस को एक अमूर्त वर्ग या उस वर्ग में लागू कर रहे हैं जो इसे विस्तारित करता है?

अमूर्त वर्ग के लिए लागू इंटरफ़ेस में एक विधि को उस सार वर्ग में लागू करने की आवश्यकता होगी। हालाँकि, उस इंटरफ़ेस को विस्तारित वर्ग पर लागू करें और विधि को केवल विस्तारित वर्ग में लागू करने की आवश्यकता है। मैं यहाँ गलत हो सकता है - मैं जितनी बार मैं कर सकता / सकती हूं, मैं इंटरफेस का उपयोग नहीं करता।

मैंने हमेशा बाहरी डेवलपर्स या चीजों को सही करने के लिए एक अतिरिक्त नियम के रूप में इंटरफेस के बारे में सोचा है।


9
PHP में, इंटरफेस में केवल विधि घोषणा है और वास्तविक कार्यान्वयन नहीं है। सार वर्ग, हालाँकि, आपको "कोड जोड़ने" की अनुमति देते हैं, ताकि इसे विस्तारित करने वाली कक्षाओं द्वारा विरासत में प्राप्त किया जा सके। मेरा मानना ​​है कि यह अंतर वही है जिसका उल्लेख एमके कर रहा था।
दोपहर

13

आप PHP में इंटरफेस का उपयोग करेंगे:

  1. कार्यान्वयन को छुपाने के लिए - वस्तुओं के एक वर्ग में एक एक्सेस प्रोटोकॉल स्थापित करें जो आपके द्वारा उपयोग किए गए सभी स्थानों पर रिफ्लेक्ट किए बिना अंतर्निहित कार्यान्वयन को बदल दें।
  2. प्रकार की जांच करने के लिए - जैसा कि यह सुनिश्चित करने के लिए कि एक पैरामीटर में एक विशिष्ट प्रकार है $object instanceof MyInterface
  3. रनटाइम पर पैरामीटर जाँच लागू करने के लिए
  4. एक वर्ग में कई व्यवहारों को लागू करना (जटिल प्रकारों का निर्माण करना)

    क्लास कार का इंजन इंजिनइंटरफेस, बॉडीइंटरफेस, स्टीयरिंगइंटरफेस {

ताकि Carअब एक ऑब्जेक्ट सीए start(), stop()(EngineInterface) या goRight(), goLeft()(स्टीयरिंग इंटरफ़ेस)

और अन्य चीजें जो मैं अभी नहीं सोच सकता

नंबर 4 यह शायद सबसे स्पष्ट उपयोग का मामला है जिसे आप अमूर्त कक्षाओं के साथ संबोधित नहीं कर सकते हैं।

जावा में सोचने से:

एक इंटरफ़ेस कहता है, "यह वह सभी कक्षाएं हैं जो इस विशेष इंटरफ़ेस को लागू करती हैं।" इस प्रकार, एक विशेष इंटरफ़ेस का उपयोग करने वाला कोई भी कोड जानता है कि उस इंटरफ़ेस के लिए क्या तरीके कहे जा सकते हैं, और यह सब है। इसलिए इंटरफ़ेस का उपयोग कक्षाओं के बीच "प्रोटोकॉल" स्थापित करने के लिए किया जाता है।


10

इंटरफेस एक आधार के रूप में मौजूद नहीं हैं, जिस पर कक्षाएं विस्तारित हो सकती हैं लेकिन आवश्यक कार्यों के मानचित्र के रूप में।

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

<?php

interface ImportableFeed 
{
    public function getEvents();
}

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

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

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

यह प्रश्न से परे है, लेकिन जब से मैंने ऊपर दिए गए उदाहरण का उपयोग किया है: इंटरफेस इस तरह से उपयोग किए जाने पर मुद्दों के अपने सेट के साथ आते हैं। मुझे लगता है कि इंटरफ़ेस से मेल खाने के लिए लागू किए गए तरीकों से लौटाए गए आउटपुट को सुनिश्चित करने के लिए मुझे स्वयं की आवश्यकता है और इसे प्राप्त करने के लिए मैं एक IDE का उपयोग करता हूं जो PHPDoc ब्लॉकों को पढ़ता है और इंटरफ़ेस के PHPDoc ब्लॉक में एक प्रकार के संकेत के रूप में रिटर्न प्रकार जोड़ता है जो तब इसे लागू करने वाले ठोस वर्ग में अनुवाद करें। मेरी कक्षाएं जो इस इंटरफ़ेस को लागू करने वाली कक्षाओं से डेटा आउटपुट का उपभोग करती हैं, वे बहुत कम से कम जानते हैं कि यह इस उदाहरण में दिए गए सरणी की उम्मीद कर रहा है:

<?php
interface ImportableFeed 
{
    /**
     * @return array
     */
    public function getEvents();
}

इसमें बहुत कुछ नहीं है जिसमें अमूर्त वर्ग और इंटरफेस की तुलना की जा सके। इंटरफेस बस मानचित्र हैं जिन्हें लागू करने के लिए वर्ग को सार्वजनिक इंटरफेस का एक सेट की आवश्यकता होती है।


अच्छी व्याख्या :) धन्यवाद!
रज़वान ४३२

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

8

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

interface Readable {
  String read();
}

List<Readable> readables; // dunno what these actually are, but we know they have read();
for(Readable reader : readables)
  System.out.println(reader.read());

कई मामलों में, एक आधार वर्ग, सार या नहीं प्रदान करने का कोई मतलब नहीं है, क्योंकि कार्यान्वयन में बेतहाशा भिन्नता है और कुछ तरीकों के अलावा आम में कुछ भी साझा नहीं करते हैं।

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


6

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

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

tl; dr: इंटरफेस उन तरीकों की एक सूची को परिभाषित करता है जिनका पालन करने की आवश्यकता है (एपीआई सोचो), जबकि एक अमूर्त वर्ग कुछ बुनियादी / सामान्य कार्यक्षमता देता है, जो उपवर्ग विशिष्ट आवश्यकताओं को परिष्कृत करते हैं।


PHP 6 कभी रिलीज़ नहीं होगी। PHP 6 एक ऐसी परियोजना थी जो 2005-2010 तक विकास के अधीन थी, लेकिन इसमें देरी हुई और अंततः इसे रद्द कर दिया गया। PHP 7 अगला संस्करण है, ज्यादातर पूर्व PHP 6 परियोजना के साथ भ्रम से बचने के लिए।
आशु झा

5

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

PHP में आप उन्हें एक अल्पविराम के साथ अलग करके कई इंटरफेस लागू कर सकते हैं (मुझे लगता है, मुझे लगता है कि एक स्वच्छ समाधान नहीं है)।

कई अमूर्त वर्गों के रूप में आप एक-दूसरे को विस्तारित करने वाले कई सार हो सकते हैं (फिर से, मुझे इस बारे में पूरी तरह से यकीन नहीं है, लेकिन मुझे लगता है कि मैंने देखा है कि पहले कहीं था)। केवल एक चीज जिसे आप विस्तारित नहीं कर सकते हैं वह एक अंतिम वर्ग है।


4

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

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

बेशक, कई-इंटरफ़ेस कार्यान्वयन के बारे में बात एक ध्वनि भी है। यदि आपके पास एक वर्ग है जो कई इंटरफेस को लागू करता है, तो आप उस वर्ग के ऑब्जेक्ट को एक ही एप्लिकेशन में विभिन्न प्रकारों के रूप में उपयोग कर सकते हैं।

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


2

नीचे PHP इंटरफ़ेस के लिए अंक दिए गए हैं

  1. इसका उपयोग कक्षा में आवश्यक तरीकों में से किसी को परिभाषित करने के लिए किया जाता है [यदि आप html को लोड करना चाहते हैं तो आईडी और नाम की आवश्यकता होती है इसलिए इस मामले में इंटरफ़ेस में setID और setName शामिल हैं]।
  2. इंटरफ़ेस कड़ाई से वर्ग को सभी तरीकों को इसमें शामिल करने के लिए मजबूर करता है।
  3. आप केवल सार्वजनिक पहुंच के साथ इंटरफ़ेस में विधि को परिभाषित कर सकते हैं।
  4. आप क्लास की तरह इंटरफ़ेस भी बढ़ा सकते हैं। आप कीवर्ड का विस्तार करके php में इंटरफ़ेस का विस्तार कर सकते हैं।
  5. कई इंटरफ़ेस बढ़ाएँ।
  6. यदि आप दोनों समान नाम के साथ फ़ंक्शन साझा करते हैं, तो आप 2 इंटरफ़ेस लागू नहीं कर सकते। यह त्रुटि फेंक देगा।

उदाहरण कोड:

interface test{
    public function A($i);
    public function B($j = 20);
}

class xyz implements test{
    public function A($a){
        echo "CLASS A Value is ".$a;
    }
    public function B($b){
        echo "CLASS B Value is ".$b;
    }
}
$x = new xyz();
echo $x->A(11);
echo "<br/>";
echo $x->B(10);

2

हमने देखा कि अमूर्त वर्ग और इंटरफेस समान हैं कि वे अमूर्त तरीके प्रदान करते हैं जिन्हें बाल कक्षाओं में लागू किया जाना चाहिए। हालाँकि, उनमें अभी भी निम्नलिखित अंतर हैं:

1.Interfaces में अमूर्त विधियाँ और स्थिरांक शामिल हो सकते हैं, लेकिन इसमें ठोस विधियाँ और चर नहीं हो सकते।

2. इंटरफ़ेस में सभी विधियाँ सार्वजनिक दृश्यता क्षेत्र में होनी चाहिए ।

3. एक वर्ग एक से अधिक इंटरफ़ेस लागू कर सकता है, जबकि यह केवल एक सार वर्ग से विरासत में मिल सकता है।

                                  interface                      abstract class
the code                     - abstract methods               - abstract methods
                             - constants                      - constants                  
                                                              - concrete methods
                                                              - concrete variables

access modifiers             
                             - public                         - public
                                                              - protected
                                                              - private
                                                                etc.
number of parents          The same class can implement
                           more than 1 interface              The child class can 
                                                              inherit only from 1 abstract class

आशा है कि यह किसी को समझने में मदद करेगा!


2

अंतर आपके जीन की तरह हैं।

सार कक्षाएं आपके वास्तविक माता-पिता की तरह हैं।

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


2

मैं अन्य भाषाओं के बारे में नहीं जानता, वहाँ इंटरफ़ेस की अवधारणा क्या है। लेकिन PHP के लिए, मैं इसे समझाने की पूरी कोशिश करूँगा। बस धैर्य रखें, और अगर यह मदद की तो कृपया टिप्पणी करें।

एक इंटरफ़ेस एक "अनुबंध" के रूप में काम करता है, यह निर्दिष्ट करता है कि उपवर्गों का एक सेट क्या करता है, लेकिन वे इसे कैसे करते हैं।

नियम

  1. एक इंटरफ़ेस तुरंत नहीं हो सकता।

  2. आप किसी भी विधि को किसी इंटरफ़ेस में लागू नहीं कर सकते, अर्थात इसमें केवल विधि की समयावधि है, लेकिन विवरण (निकाय) नहीं।

  3. इंटरफेस में विधियाँ और / या स्थिरांक हो सकते हैं, लेकिन कोई विशेषता नहीं। इंटरफ़ेस स्थिरांक पर कक्षा के स्थिरांक के समान प्रतिबंध हैं। इंटरफ़ेस तरीके संक्षेप में सार हैं।

  4. इंटरफेसेस को कंस्ट्रक्टर या डिस्ट्रक्टर्स की घोषणा नहीं करनी चाहिए, क्योंकि ये क्लास स्तर पर कार्यान्वयन विवरण हैं।

  5. एक इंटरफ़ेस की सभी विधियों में सार्वजनिक दृश्यता होनी चाहिए।

अब एक उदाहरण लेते हैं। मान लीजिए हमारे पास दो खिलौने हैं: एक कुत्ता है, और दूसरा एक बिल्ली है।

जैसा कि हम जानते हैं कि एक कुत्ता भौंकता है, और बिल्ली मेवेस। ये दो एक ही बोलने की विधि है, लेकिन विभिन्न कार्यक्षमता या कार्यान्वयन के साथ। मान लीजिए हम उपयोगकर्ता को एक रिमोट कंट्रोल दे रहे हैं जिसमें एक स्पीक बटन है।

जब उपयोगकर्ता बोलता बटन दबाता है, तो खिलौना को बोलना पड़ता है कि क्या यह कुत्ता या बिल्ली नहीं है।

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

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

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