अमूर्त वर्ग, इंटरफेस और उन्हें कब उपयोग करना है, इसके बीच क्या अंतर हैं


15

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

मैं अपनी विशिष्ट स्थिति के माध्यम से इनके बारे में अधिक जानना चाहूंगा। यहाँ मेरे पहले प्रश्न की एक कड़ी है यदि आप थोड़ी अधिक पृष्ठभूमि की जानकारी चाहते हैं: मेरे नए वर्ग के लिए एक अच्छा डिज़ाइन मॉडल क्या है?

यहां मैंने दो कक्षाएं बनाई हैं:

class Ad {
    $title;
    $description
    $price;

    function get_data($website){  }

    function validate_price(){  }
 }


class calendar_event {
    $title;
    $description

    $start_date;

    function get_data($website){ //guts }

    function validate_dates(){ //guts }
 }

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

अब मैंने DRY सिद्धांत का उल्लंघन किया है और मैं एक ही कोड को कई फाइलों में बदल रहा हूं। मैं नावों, घोड़ों, या जो भी हो, जैसे अधिक कक्षाएं लेने का इरादा रखता हूं।

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

abstract class content {
    $title;
    $description


    function get_data($website){  }

    function common_function2() { }
    function common_function3() { }
 }


class calendar_event extends content {

    $start_date;

    function validate_dates(){  }
 }

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

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

धन्यवाद!


ऑनलाइन बहुत सारे अच्छे उदाहरण हैं। मुझे लगता है कि यह उनमें से एक है। javapapers.com/core-java/abstract-and-interface-core-java-2/…
Siva

जवाबों:


26

आम आदमी की शर्तों में:

इंटरफेस के लिए कर रहे हैं "क्या कर सकते हैं / के रूप में इलाज किया जा सकता" रिश्ते के प्रकार।

सार (और साथ ही ठोस) वर्ग के लिए कर रहे हैं "एक" रिश्ते की तरह।

इन उदाहरणों को देखो:

class Bird extends Animal implements Flight;
class Plane extends Vehicle implements Flight, AccountableAsset;
class Mosquito extends Animal implements Flight;
class Horse extends Animal;
class RaceHorse extends Horse implements AccountableAsset;
class Pegasus extends Horse implements Flight;

Bird, Mosquitoऔर Horse हैं Animals । वे संबंधित हैं। उन्हें जानवरों की तरह सामान्य तरीके विरासत में मिलते हैं eat(), metabolize() and reproduce()। हो सकता है कि वे इन तरीकों को ओवरराइड करते हैं, उनके लिए थोड़ा अतिरिक्त जोड़ते हैं, लेकिन वे एनिमल जैसे कार्यान्वित डिफ़ॉल्ट व्यवहार का लाभ उठाते हैंmetabolizeGlucose().

Planeसे संबंधित नहीं है Bird, Mosquitoया Horse

Flightअसंतुष्ट, असंबद्ध वर्गों, जैसे Birdऔर द्वारा कार्यान्वित किया जाता है Plane

AccountableAssetयह भी असंतुष्ट, असंबद्ध वर्गों, जैसे Planeऔर द्वारा कार्यान्वित किया जाता है RaceHorse

Horse उड़ान को लागू नहीं करता है।

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

दूसरी ओर, इंटरफेस , कोई पदानुक्रम नहीं बनाते हैं, लेकिन वे पदानुक्रम में कुछ व्यवहारों को समरूप बनाने में मदद कर सकते हैं ताकि आप उन्हें कुछ संदर्भों में पदानुक्रम से सार कर सकें।

उदाहरण के लिए आप एक प्रोग्राम के एक समूह के मूल्य का योग हो सकता है AccountableAssetsउनके जा रहा है की परवाह किए बिना RaceHorsesया Planes


गजब का। इंटरफ़ेस कार्यक्षमता का एक निश्चित खंड प्रदान करता है जो can do/can be treated asकि जहां अमूर्त वर्ग नींव के रूप में कार्य करता है, वहां लगाता है !
अभिरोज पंवार

13

जब आप दोनों के बीच के मतभेदों से अवगत होते हैं तो आप उत्तर को तार्किक रूप से काट सकते हैं।

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

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

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

इसके अलावा, लगता है कि Google में परिणामों की कोई कमी नहीं है।


3

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

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

आशा है कि मदद करता है, लेकिन इस ऑनलाइन, लियो पर बहुत सारी जानकारी है


2
Classes cannot have multiple inheritance- जावा और C # जैसी भाषाओं के लिए सही, C ++ के लिए सही नहीं।
रॉबर्ट हार्वे

3

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

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

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

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


3

अंतर सूक्ष्म है लेकिन स्पष्ट है। इंटरफ़ेस बहुरूपी व्यवहार के बारे में है। सार वर्ग पुन: उपयोग और बहुरूपी व्यवहार के बारे में है।

यदि आप पुन: उपयोग और बहुरूपी व्यवहार पर जोर देना चाहते हैं, तो सार वर्ग चुनें। उदाहरण के लिए, विभिन्न प्रकार के कर्मचारियों के अलग-अलग प्रावधान हैं, लेकिन सभी कुछ सामान्य हैं। तो, अमूर्त वर्ग इसका प्रतिनिधित्व करने के लिए उपयुक्त है क्योंकि एक आधार सार वर्ग में समानताएं व्यक्त की जा सकती हैं Employeeऔर अंतर को व्युत्पन्न वर्गों जैसे Managerया Workerआदि में लागू किया जा सकता है ।

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


-3
  1. मुख्य अंतर एक जावा इंटरफेस की विधियां हैं, जो संक्षेप में सार हैं और इसमें कार्यान्वयन नहीं हो सकते हैं। जावा सार वर्ग में ऐसे तरीके हो सकते हैं जो एक डिफ़ॉल्ट व्यवहार को लागू करते हैं।
  2. एक जावा इंटरफेस में घोषित चर डिफ़ॉल्ट रूप से होता है। एक अमूर्त वर्ग में गैर-अंतिम चर हो सकते हैं।
  3. जावा इंटरफ़ेस के सदस्य डिफ़ॉल्ट रूप से सार्वजनिक होते हैं। एक जावा अमूर्त वर्ग में कक्षा के सदस्यों के सामान्य स्वाद हो सकते हैं जैसे निजी, संरक्षित, आदि।
  4. जावा इंटरफ़ेस को कीवर्ड "इम्प्लीमेंट्स" का उपयोग करके लागू किया जाना चाहिए; एक जावा अमूर्त वर्ग को कीवर्ड "एक्सटेंड्स" का उपयोग करके बढ़ाया जाना चाहिए।
  5. एक इंटरफ़ेस एक और जावा इंटरफ़ेस का विस्तार कर सकता है केवल एक सार वर्ग दूसरे जावा वर्ग का विस्तार कर सकता है और कई जावा इंटरफेस को लागू कर सकता है।
  6. एक जावा वर्ग कई इंटरफेस को लागू कर सकता है लेकिन यह केवल एक सार वर्ग का विस्तार कर सकता है।
  7. इंटरफ़ेस बिल्कुल सार है और इसे तुरंत नहीं किया जा सकता है; एक जावा अमूर्त वर्ग को भी तत्काल नहीं किया जा सकता है, लेकिन यदि मुख्य () मौजूद है तो इसे लागू किया जा सकता है।
  8. जावा अमूर्त वर्गों की तुलना में, जावा इंटरफेस धीमा हैं क्योंकि इसके लिए अतिरिक्त अप्रत्यक्षता की आवश्यकता होती है।
  9. जावा में इंटरफ़ेस और अमूर्त वर्ग यह है कि आप इंटरफ़ेस में गैर सार विधि नहीं बना सकते हैं, इंटरफ़ेस में प्रत्येक विधि डिफ़ॉल्ट सार द्वारा है, लेकिन आप सार वर्ग में गैर सार विधि बना सकते हैं।
  10. जावा में एब्सट्रैक्ट क्लास बनाम इंटरफ़ेस यह है कि टाइप डिक्लेरेशन के लिए इंटरफेस बेहतर अनुकूल हैं और अमूर्त क्लास कोड के पुन: उपयोग और विकास के परिप्रेक्ष्य के लिए अधिक अनुकूल है।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.