जवाबों:
जब आप अपने सिस्टम में काम करने वाले डेवलपर्स (जब आप शामिल हैं) को उन वर्गों की विधियों की एक निर्धारित संख्या को लागू करने के लिए बाध्य करना चाहते हैं, तो वे एक इंटरफ़ेस का उपयोग करें।
जब आप (अपने आप को शामिल) आपके सिस्टम में काम कर रहे तरीकों का एक सेट संख्या को लागू करने की शक्ति डेवलपर्स के लिए चाहते हैं एक अमूर्त वर्ग का उपयोग करें और आप कुछ आधार तरीके प्रदान करना चाहते हैं जो उन्हें अपने बच्चे की कक्षाओं को विकसित करने में मदद करेंगे।
ग्राहक वर्गों को ध्यान में रखते हुए एक और बात केवल एक सार वर्ग का विस्तार कर सकती है, जबकि वे कई इंटरफेस को लागू कर सकते हैं। इसलिए, यदि आप अमूर्त कक्षाओं में अपने व्यवहार अनुबंधों को परिभाषित कर रहे हैं, तो इसका मतलब है कि प्रत्येक बच्चा वर्ग केवल एक अनुबंध के अनुरूप हो सकता है। कभी-कभी यह एक अच्छी बात है, जब आप अपने उपयोगकर्ता-प्रोग्रामर्स को एक विशेष पथ के साथ बाध्य करना चाहते हैं। अन्य समय यह बुरा होगा। कल्पना कीजिए कि अगर PHP के गणनीय और Iterator इंटरफेस इंटरफेस के बजाय अमूर्त वर्ग थे।
एक दृष्टिकोण जो सामान्य है जब आप अनिश्चित होते हैं कि किस रास्ते पर जाना है (जैसा कि नीचे दिए गए क्लेटस द्वारा उल्लेख किया गया है ) एक इंटरफ़ेस बनाना है, और फिर आपके सार वर्ग को उस इंटरफ़ेस को लागू करना है।
एक Abstract Class
और एक के बीच का अंतर Interface
:
सार वर्ग
एक अमूर्त वर्ग कुछ कार्यक्षमता प्रदान कर सकता है और बाकी को व्युत्पन्न वर्ग के लिए छोड़ सकता है ।
व्युत्पन्न वर्ग बेस क्लास में परिभाषित ठोस कार्यों को ओवरराइड कर सकता है या नहीं कर सकता है ।
अमूर्त वर्ग से विस्तारित एक बाल वर्ग तार्किक रूप से संबंधित होना चाहिए।
इंटरफेस
एक इंटरफ़ेस में कोई कार्यक्षमता नहीं हो सकती । इसमें केवल विधियों की परिभाषाएँ हैं।
व्युत्पन्न वर्ग MUST इंटरफ़ेस में परिभाषित सभी तरीकों के लिए कोड प्रदान करता है ।
पूरी तरह से अलग और गैर-संबंधित कक्षाएं एक इंटरफ़ेस का उपयोग करके तार्किक रूप से समूहीकृत की जा सकती हैं।
abstract class X implements Y
और class X implements Y
?
abstract class X implements Y
आप यह घोषणा करते हैं कि एक्स की थोक कार्यक्षमता को एक व्युत्पन्न वर्ग में लागू किया जाना चाहिए और यह है कि सार और व्युत्पन्न दोनों वर्ग में वाई में परिभाषित कार्य शामिल होने चाहिए , जबकि class X implements Y
इसका मतलब है कि कक्षा एक्स में वाई में परिभाषित फ़ंक्शन शामिल होने चाहिए। यदि आपका इंटरफ़ेस वाई XI की तुलना में किसी अन्य वर्ग द्वारा कार्यान्वित किए जाने का इरादा नहीं है, वास्तव में Y को एक इंटरफ़ेस के रूप में परिभाषित करना छोड़ देगा और केवल Y में कार्यों को सार्वजनिक / संरक्षित / निजी अमूर्त फ़ंक्शन के रूप में कार्यान्वित करेगा, यह सुनिश्चित करने के लिए कि वे व्युत्पन्न वर्ग में लागू किए गए हैं।
अमूर्त वर्गों का उपयोग क्यों करें? निम्नलिखित एक सरल उदाहरण है। हम कहते हैं कि हमारे पास निम्नलिखित कोड हैं:
<?php
class Fruit {
private $color;
public function eat() {
// chew
}
public function setColor($c) {
$this->color = $c;
}
}
class Apple extends Fruit {
public function eat() {
// chew until core
}
}
class Orange extends Fruit {
public function eat() {
// peeling
// chew
}
}
अब मैं आपको एक सेब देता हूं और आप इसे खाते हैं। इसका स्वाद किस तरह का है? इसका स्वाद सेब जैसा होता है।
<?php
$apple = new Apple();
$apple->eat();
// Now I give you a fruit.
$fruit = new Fruit();
$fruit->eat();
उस स्वाद को क्या पसंद है? ठीक है, यह बहुत मतलब नहीं है, तो आप ऐसा करने में सक्षम नहीं होना चाहिए। यह फ्रूट क्लास को सार बनाने के साथ-साथ इसके अंदर खाने की विधि को भी पूरा करता है।
<?php
abstract class Fruit {
private $color;
abstract public function eat(){}
public function setColor($c) {
$this->color = $c;
}
}
?>
एक अमूर्त वर्ग एक अंतरफलक की तरह है, लेकिन आप एक सार वर्ग में तरीकों को परिभाषित कर सकते हैं जबकि एक इंटरफ़ेस में वे सभी सार हैं। अमूर्त कक्षाएं खाली और काम करने वाले / ठोस दोनों तरीके हो सकती हैं। इंटरफेस में, परिभाषित कार्यों में एक शरीर नहीं हो सकता है। अमूर्त वर्गों में, वे कर सकते हैं।
एक वास्तविक दुनिया उदाहरण:
<?php
abstract class person {
public $LastName;
public $FirstName;
public $BirthDate;
abstract protected function write_info();
}
final class employee extends person{
public $EmployeeNumber;
public $DateHired;
public function write_info(){
//sql codes here
echo "Writing ". $this->LastName . "'s info to emloyee dbase table <br>";
}
}
final class student extends person{
public $StudentNumber;
public $CourseName;
public function write_info(){
//sql codes here
echo "Writing ". $this->LastName . "'s info to student dbase table <br>";
}
}
///----------
$personA = new employee;
$personB = new student;
$personA->FirstName="Joe";
$personA->LastName="Sbody";
$personB->FirstName="Ben";
$personB->LastName="Dover";
$personA->write_info();
// Writing Sbody's info to emloyee dbase table
$personB->write_info();
// Writing Dover's info to student dbase table
What does that taste like? Well, it doesn't make much sense, so you shouldn't be able to do that.
अब मैं अमूर्त जानता हूं!
final
कीवर्ड क्या करता है? शानदार पोस्ट, धन्यवाद।
सबसे अच्छा अभ्यास अनुबंध और एक अमूर्त वर्ग को केवल एक कार्यान्वयन के रूप में निर्दिष्ट करने के लिए एक इंटरफ़ेस का उपयोग करना है। वह अमूर्त वर्ग बहुत सारे बॉयलरप्लेट में भर सकता है ताकि आप केवल एक विशेष कार्यान्वयन का उपयोग करने के लिए मजबूर किए बिना आपको क्या चाहिए या क्या चाहते हैं, ओवरराइड करके एक कार्यान्वयन बना सकते हैं।
बस इस मिश्रण में फेंकने के लिए, लेकिन जैसा कि क्लेटस ने एक सार वर्ग के साथ संयोजन में एक इंटरफ़ेस का उपयोग करते हुए उल्लेख किया है, मैं अक्सर अपनी डिजाइन सोच को स्पष्ट करने के लिए इंटरफ़ेस का उपयोग करता हूं।
उदाहरण के लिए:
<?php
class parser implements parserDecoratorPattern {
//...
}
इस तरह, कोई भी मेरे कोड को पढ़ रहा है (और जो जानता है कि डेकोरेटर पैटर्न क्या है) को तुरंत पता चल जाएगा) मैं कैसे अपने पार्सर और बी का निर्माण करता हूं, यह देखने में सक्षम हो सकता है कि डेकोरेटर पैटर्न को लागू करने के लिए कौन से तरीकों का उपयोग किया जाता है।
इसके अलावा, और मैं यहाँ जावा / सी ++ / आदि प्रोग्रामर नहीं होने के आधार पर बंद हो सकता हूं, लेकिन डेटा प्रकार यहाँ खेलने में आ सकते हैं। आपकी वस्तुएं एक प्रकार की होती हैं, और जब आप उन्हें टाइप करते हैं तो प्रोग्राम के अनुसार टाइप करते हैं। इंटरफ़ेस में अपने अनुबंधित आइटम को ले जाने से केवल उन प्रकारों को निर्धारित किया जाता है जो विधियाँ वापस आती हैं, लेकिन आधार प्रकार का नहीं जो इसे लागू करता है।
देर हो चुकी है और मैं एक बेहतर छद्म-कोड उदाहरण के बारे में नहीं सोच सकता, लेकिन यहाँ जाता है:
<?php
interface TelevisionControls {};
class Remote implements TelevisionControls {};
class Spouse implements TelevisionControls {};
Spouse spouse = new Spouse();
Remote remote = new Remote();
isSameType = (bool)(remote == spouse)
इसके अलावा, बस यहाँ जोड़ना चाहते हैं कि सिर्फ इसलिए कि किसी भी अन्य ओओ भाषा में कुछ प्रकार के इंटरफेस और अमूर्तता हैं, इसका मतलब यह भी नहीं है कि उनके पास पीएचपी के समान अर्थ और उद्देश्य हैं। एब्सट्रैक्ट / इंटरफेस का उपयोग थोड़ा अलग है, जबकि PHP में इंटरफेस वास्तव में एक वास्तविक फ़ंक्शन नहीं है। वे केवल शब्दार्थ और योजना से संबंधित कारणों के लिए उपयोग किया जाता है। मुद्दा यह है कि भविष्य के एक्सटेंशन के लिए जितना संभव हो उतना लचीला, एक परियोजना हो और बाद में डेवलपर के उपयोग की पूरी तरह से अलग योजना हो या न हो।
यदि आपकी अंग्रेजी मूल नहीं है तो आप देख सकते हैं कि वास्तव में एब्सट्रैक्शन और इंटरफेस क्या हैं। और पर्यायवाची भी देखो।
और यह आपको एक रूपक के रूप में मदद कर सकता है:
इंटरफेस
मान लीजिए, आप स्ट्रॉबेरी के साथ एक नए प्रकार का केक बनाते हैं और आपने सामग्री और चरणों का वर्णन करते हुए एक नुस्खा बनाया है। केवल आप ही जानते हैं कि यह इतनी अच्छी तरह से क्यों चखा जा रहा है और आपके मेहमान इसे पसंद करते हैं। फिर आप अपना नुस्खा प्रकाशित करने का निर्णय लेते हैं ताकि अन्य लोग भी उस केक को आजमा सकें।
यहाँ मुद्दा यह है
- इसे सही बनाने के लिए
- सावधानी बरतने के लिए
-
उन चीजों को रोकने के लिए जो खराब हो सकती हैं (जैसे बहुत स्ट्रॉबेरी या कुछ और) - इसे आज़माने वाले लोगों के लिए आसान रखने के लिए
- आपको यह बताने के लिए कि कब तक क्या करना है (जैसे स्टायरिंग )
- यह बताने के लिए कि आप कौन सी चीजें कर सकते हैं लेकिन करना नहीं है
वास्तव में यह वह है जो इंटरफेस का वर्णन करता है। यह एक गाइड है, निर्देशों का एक सेट जो नुस्खा की सामग्री का निरीक्षण करता है। उसी तरह जैसे कि आप PHP में एक प्रोजेक्ट बनाएंगे और आप GitHub पर या अपने साथियों या जो भी हो, को कोड प्रदान करना चाहते हैं। एक इंटरफेस है कि लोग क्या कर सकते हैं और आपको क्या नहीं करना चाहिए। नियम जो इसे पकड़ते हैं - यदि आप एक की अवज्ञा करते हैं, तो पूरा निर्माण टूट जाएगा।
मतिहीनता
यहां इस रूपक के साथ जारी रखने के लिए ... कल्पना कीजिए, आप इस बार उस केक को खाने वाले मेहमान हैं। तो फिर आप उस केक का उपयोग कर रहे हैं अब नुस्खा का उपयोग कर। लेकिन आप नई सामग्री जोड़ना या बदलना / नुस्खा में वर्णित चरणों को छोड़ना चाहते हैं। तो आगे क्या आता है? उस केक के एक अलग संस्करण की योजना बनाएं। इस बार काले जामुन और नहीं पुआल जामुन और अधिक वेनिला क्रीम के साथ ... स्वादिष्ट।
यह वही है जो आप मूल केक के विस्तार पर विचार कर सकते हैं। आप मूल रूप से एक नया नुस्खा बनाकर इसके बारे में अमूर्त करते हैं क्योंकि यह एक अलग है। इसमें कुछ नए कदम और अन्य सामग्री है। हालाँकि, ब्लैक बेरी संस्करण के कुछ हिस्से हैं जिन्हें आपने मूल से लिया है - ये आधार चरण हैं जो हर तरह के केक के पास होने चाहिए। दूध के रूप में सामग्री की तरह - यह है कि हर व्युत्पन्न वर्ग है।
अब आप सामग्री और चरणों का आदान-प्रदान करना चाहते हैं और इन MUST को उस केक के नए संस्करण में परिभाषित किया जाना चाहिए। ये अमूर्त तरीके हैं जिन्हें नए केक के लिए परिभाषित किया जाना है, क्योंकि केक में एक फल होना चाहिए लेकिन कौन सा? तो आप इस बार काले जामुन का सेवन करें। किया हुआ।
वहां आप जाते हैं, आपने केक को बढ़ाया है, इंटरफ़ेस का पालन किया है और इसमें से अमूर्त कदम और सामग्री।
पहले से ही उत्कृष्ट उत्तरों में से कुछ को जोड़ने के लिए:
अमूर्त कक्षाएं आपको कुछ हद तक कार्यान्वयन प्रदान करती हैं, इंटरफेस शुद्ध टेम्पलेट हैं। एक इंटरफ़ेस केवल कार्यक्षमता को परिभाषित कर सकता है , इसे कभी लागू नहीं कर सकता।
कोई भी वर्ग जो इंटरफ़ेस को लागू करता है वह सभी तरीकों को लागू करने के लिए प्रतिबद्ध करता है जो इसे परिभाषित करता है या इसे सार घोषित किया जाना चाहिए।
इंटरफेस इस तथ्य को प्रबंधित करने में मदद कर सकते हैं कि, जावा की तरह, PHP कई उत्तराधिकार का समर्थन नहीं करता है। एक PHP वर्ग केवल एक ही माता-पिता का विस्तार कर सकता है। हालाँकि, आप जितने चाहें उतने इंटरफ़ेस लागू करने के लिए एक क्लास वादा कर सकते हैं।
प्रकार: प्रत्येक इंटरफ़ेस के लिए यह लागू होता है, वर्ग इसी प्रकार लेता है। क्योंकि कोई भी वर्ग एक इंटरफ़ेस (या अधिक इंटरफेस) को लागू कर सकता है, इंटरफेस प्रभावी रूप से उन प्रकारों से जुड़ते हैं जो अन्यथा असंबंधित हैं।
एक वर्ग दोनों एक सुपरक्लास का विस्तार कर सकता है और किसी भी इंटरफेस को लागू कर सकता है:
class SubClass extends ParentClass implements Interface1, Interface2 {
// ...
}
कृपया बताएं कि मुझे इंटरफ़ेस का उपयोग कब करना चाहिए और मुझे सार वर्ग का उपयोग कब करना चाहिए?
एक इंटरफ़ेस का उपयोग करें जब आपको कोई कार्यान्वयन के साथ केवल एक टेम्प्लेट प्रदान करने की आवश्यकता है जो कभी भी ऐसा हो, और आप यह सुनिश्चित करना चाहते हैं कि कोई भी वर्ग जो कि इंटरफ़ेस को लागू करता है, उसके पास किसी अन्य वर्ग के समान तरीके होंगे जो इसे लागू करता है (कम से कम)।
जब आप अन्य वस्तुओं (आंशिक रूप से निर्मित वर्ग) के लिए नींव बनाना चाहते हैं तो एक सार वर्ग का उपयोग करें। वह वर्ग जो आपके अमूर्त वर्ग का विस्तार करता है, परिभाषित / कार्यान्वित कुछ गुणों या विधियों का उपयोग करेगा:
<?php
// interface
class X implements Y { } // this is saying that "X" agrees to speak language "Y" with your code.
// abstract class
class X extends Y { } // this is saying that "X" is going to complete the partial class "Y".
?>
मैं अपने सार वर्ग को एक इंटरफ़ेस में कैसे बदल सकता हूं?
यहाँ एक सरलीकृत मामला / उदाहरण है। कोई भी कार्यान्वयन विवरण निकाल लें। उदाहरण के लिए, अपने अमूर्त वर्ग को निम्न से बदलें:
abstract class ClassToBuildUpon {
public function doSomething() {
echo 'Did something.';
}
}
सेवा:
interface ClassToBuildUpon {
public function doSomething();
}
एक फिलोसोफिक दृष्टिकोण से:
एक अमूर्त वर्ग एक "एक" संबंध है। आइए हम कहते हैं कि मेरे पास फल हैं, अच्छी तरह से मेरे पास एक फलों का सार वर्ग होगा जो सामान्य जिम्मेदारियों और सामान्य व्यवहार को साझा करता है।
एक इंटरफ़ेस एक "करना चाहिए" रिश्ते का प्रतिनिधित्व करता है। एक इंटरफ़ेस, मेरी राय में (जो एक जूनियर देव की राय है), एक कार्रवाई द्वारा नामित किया जाना चाहिए, या एक कार्रवाई के करीब कुछ, (क्षमा करें, शब्द नहीं मिल सकता है, मैं एक अंग्रेजी मूल वक्ता नहीं हूं) आईईटेबल कहते हैं। आप जानते हैं कि इसे खाया जा सकता है, लेकिन आप नहीं जानते कि आप क्या खाते हैं।
कोडिंग के दृष्टिकोण से:
यदि आपकी वस्तुओं ने कोड को डुप्लिकेट किया है, तो यह एक संकेत है कि उनके पास सामान्य व्यवहार है, जिसका अर्थ है कि आपको कोड का पुन: उपयोग करने के लिए एक अमूर्त वर्ग की आवश्यकता हो सकती है, जिसे आप इंटरफ़ेस के साथ नहीं कर सकते।
एक और अंतर यह है कि कोई वस्तु जितनी आवश्यकता हो उतने इंटरफेस को लागू कर सकती है, लेकिन "डायमंड प्रॉब्लम" की वजह से आप केवल एक एब्सट्रैक्ट क्लास रख सकते हैं (यह जानने के लिए यहां देखें! Http://en.wikipedia.org/wiki/ एकाधिक_संहिता # The_diamond_problem )
मैं शायद कुछ बिंदु भूल जाता हूं, लेकिन मुझे उम्मीद है कि यह चीजों को स्पष्ट कर सकता है।
पुनश्च: "एक" / "करना चाहिए" विवेक वर्मनी के उत्तर द्वारा लाया गया है, मुझे इसका जवाब चोरी करने का मतलब नहीं था, सिर्फ शर्तों का पुन: उपयोग करने के लिए क्योंकि मैं उन्हें पसंद करता था!
एक अमूर्त वर्ग और एक अंतरफलक के बीच तकनीकी अंतर पहले से ही अन्य उत्तरों में सूचीबद्ध हैं। मैं ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग के लिए कोड लिखते समय क्लास और इंटरफ़ेस के बीच चयन करने के लिए स्पष्टीकरण जोड़ना चाहता हूं।
एक वर्ग को एक इकाई का प्रतिनिधित्व करना चाहिए जबकि एक इंटरफ़ेस को व्यवहार का प्रतिनिधित्व करना चाहिए।
एक उदाहरण लेते हैं। एक कंप्यूटर मॉनीटर एक इकाई है और इसे एक वर्ग के रूप में दर्शाया जाना चाहिए।
class Monitor{
private int monitorNo;
}
यह आपको एक प्रदर्शन इंटरफ़ेस प्रदान करने के लिए डिज़ाइन किया गया है, इसलिए कार्यक्षमता को इंटरफ़ेस द्वारा परिभाषित किया जाना चाहिए।
interface Display{
void display();
}
अन्य उत्तरों में बताई गई बातों पर विचार करने के लिए कई अन्य चीजें हैं, लेकिन यह सबसे बुनियादी चीज है जिसे ज्यादातर लोग कोडिंग करते समय अनदेखा कर देते हैं।
PHP
जब आप दोनों का उपयोग करने की आवश्यकता कर सकते हैं तो बस एक उदाहरण जोड़ना चाहते थे। मैं वर्तमान में एक सामान्य प्रयोजन ईआरपी समाधान में एक डेटाबेस मॉडल के लिए बाध्य एक फ़ाइल हैंडलर लिख रहा हूं।
इस तरह, मुझे विभिन्न फ़ाइलों के लिए कई टेम्पलेट मिलते हैं और स्पष्ट अंतर के साथ इंटरफ़ेस विधियों का एक सामान्य सेट। इंटरफ़ेस एक आधार अमूर्त वर्ग के साथ क्या होता है इसके बजाय पहुँच विधियों को सही सादृश्य देता है।
जब मैं विभिन्न फ़ाइल भंडारण सेवाओं के लिए एडेप्टर बनाऊंगा, तो लाइन के नीचे, यह कार्यान्वयन पूरी तरह से अलग संदर्भों में इंटरफ़ेस को कहीं और उपयोग करने की अनुमति देगा।
abstract
औरinterface
कक्षाओं को समझने के लिए , आपकी पोस्ट ने इसे स्पष्ट कर दिया। बहुत बहुत धन्यवाद एलन