2008-08-21 17 views
187

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

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

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

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

+3

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

+0

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

उत्तर

127

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

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

+31

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

+0

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

+11

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

115

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

+0

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

+0

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

18

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

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

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

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

+8

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

5

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

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

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

+0

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

5

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

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()); 

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

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

4

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

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

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

3

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

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

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

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

20

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

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

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

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

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

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

+0

यह ठीक है यहाँ। – Nick

9

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

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

    वर्ग कार को लागू करता है EngineInterface, BodyInterface, SteeringInterface {

ताकि एक Car वस्तु ca अब start(), stop() (EngineInterface) या goRight(), goLeft() (संचालन इंटरफेस)

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

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

जावा में सोच रही थी से:

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

46

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

इस तरह की समस्याओं में से एक:

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

स्रोत: 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() (इस उदाहरण में) होगी और कॉल/उपयोग करने के लिए केवल 1 पैरामीटर ($personObject) की आवश्यकता होगी।

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

मुझे उम्मीद है कि मैंने खुद को दोहराया नहीं है।

9

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

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

<?php 

interface ImportableFeed 
{ 
    public function getEvents(); 
} 

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

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

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

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

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

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

+0

अच्छी व्याख्या के बिना अपने तरीकों का उपयोग करने के लिए देवताओं को कठोर रूप से लागू करें :) धन्यवाद! –

+0

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

1

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

  1. यह इसलिए इस मामले इंटरफ़ेस में 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); 
0

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

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

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 

आशा इस वसीयत को समझने के लिए किसी को भी मदद करता है!

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