मुझे इंटरफ़ेस और अमूर्त वर्ग के बीच अंतर कैसे समझाया जाना चाहिए?


469

मेरे एक साक्षात्कार में, मुझे एक इंटरफ़ेस और एक सार वर्ग के बीच के अंतर को समझाने के लिए कहा गया है ।

यहाँ मेरी प्रतिक्रिया है:

एक जावा इंटरफेस के तरीके स्पष्ट रूप से सार हैं और कार्यान्वयन नहीं हो सकते हैं। जावा अमूर्त वर्ग में ऐसे तरीके हो सकते हैं जो एक डिफ़ॉल्ट व्यवहार को लागू करते हैं।

जावा इंटरफेस में घोषित चर डिफ़ॉल्ट रूप से होते हैं। एक अमूर्त वर्ग में गैर-अंतिम चर हो सकते हैं।

जावा इंटरफ़ेस के सदस्य डिफ़ॉल्ट रूप से सार्वजनिक होते हैं। एक जावा अमूर्त वर्ग में निजी, संरक्षित, आदि जैसे वर्ग के सदस्यों के सामान्य स्वाद हो सकते हैं।

एक जावा इंटरफेस को कीवर्ड "इम्प्लीमेंट्स" का उपयोग करके लागू किया जाना चाहिए; एक जावा एब्स्ट्रैक्ट क्लास को कीवर्ड "एक्सटेंड्स" का उपयोग करके बढ़ाया जाना चाहिए।

एक इंटरफ़ेस केवल एक और जावा इंटरफ़ेस का विस्तार कर सकता है, एक अमूर्त वर्ग दूसरे जावा वर्ग का विस्तार कर सकता है और कई जावा इंटरफेस को लागू कर सकता है।

एक जावा वर्ग कई इंटरफेस को लागू कर सकता है लेकिन यह केवल एक सार वर्ग का विस्तार कर सकता है।

हालांकि, साक्षात्कारकर्ता संतुष्ट नहीं थे, और मुझे बताया कि यह विवरण " किताबी ज्ञान " का प्रतिनिधित्व करता है ।

उन्होंने मुझसे और अधिक व्यावहारिक प्रतिक्रिया के लिए कहा, यह समझाते हुए कि मैं व्यावहारिक उदाहरणों का उपयोग करते हुए एक इंटरफ़ेस पर एक अमूर्त वर्ग कैसे चुनूंगा

मुझसे कहां गलती हो गई?


32
हो सकता है कि आपका जवाब ऐसा लगे जैसे आप कुछ बता रहे हैं जो आपको समझ में नहीं आ रहा है? यह हो सकता है कि आपको बस यह बताने की शैली को बदलने की ज़रूरत है कि आपके अपने शब्दों की तरह अधिक दिखता है।
किरिल कोबेलेव

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

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

7
जावा 8 इंटरफेस में विधियाँ हो सकती हैं .. इसलिए OO अवधारणा से परे ये तथाकथित "अंतर" किसी भी दिन बदल सकते हैं।
रिंग बियरर

15
मुझे आपके उत्तर से कोई समस्या नहीं है, और मुझे नहीं लगता कि साक्षात्कारकर्ता के पास 'किताबी ज्ञान' में किसी तरह का व्यवसाय है। साक्षात्कारकर्ता हमेशा पूछे जाने वाले प्रश्नों के सही उत्तर नहीं जानते हैं, और कुछ साक्षात्कार केवल आपको काम नहीं करने की चेतावनी देते हैं।
लोर्ने

जवाबों:


513

मैं आपको पहले एक उदाहरण दूंगा:

public interface LoginAuth{
   public String encryptPassword(String pass);
   public void checkDBforUser();
}

मान लीजिए कि आपके आवेदन में 3 डेटाबेस हैं। फिर उस डेटाबेस के लिए प्रत्येक कार्यान्वयन को उपरोक्त 2 विधियों को परिभाषित करने की आवश्यकता है:

public class DBMySQL implements LoginAuth{
          // Needs to implement both methods
}
public class DBOracle implements LoginAuth{
          // Needs to implement both methods
}
public class DBAbc implements LoginAuth{
          // Needs to implement both methods
}

लेकिन क्या होगा अगर encryptPassword()डेटाबेस निर्भर नहीं है, और यह प्रत्येक वर्ग के लिए समान है? फिर ऊपर एक अच्छा दृष्टिकोण नहीं होगा।

इसके बजाय, इस दृष्टिकोण पर विचार करें:

public abstract class LoginAuth{
   public String encryptPassword(String pass){
            // Implement the same default behavior here 
            // that is shared by all subclasses.
   }

   // Each subclass needs to provide their own implementation of this only:
   public abstract void checkDBforUser();
}

अब प्रत्येक बाल वर्ग में, हमें केवल एक विधि को लागू करने की आवश्यकता है - वह विधि जो डेटाबेस पर निर्भर है।


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

1
@Thecoshman यदि मुझे उत्तर के रूप में समस्या का सामना करना पड़ा तो क्या अंतर होगा (अमूर्त वर्ग एक विधि के साथ लागू किया गया और दूसरा सार) या एक डिफ़ॉल्ट विधि कार्यान्वयन के साथ एक इंटरफ़ेस परिभाषित किया गया? मूल रूप से, मैं जो कहना चाह रहा हूं वह यह है कि आपने लिखा है कि 'एक इंटरफेस का उपयोग करना बेहतर होगा' और मेरा सवाल है - क्यों?
न्यूट्रिनो

1
इसलिए, मुझे लगता है कि यह कहना उचित है कि इंटरफेस के साथ, जो परिभाषित किया गया है उसका कार्यान्वयन उस वर्ग तक है जो वास्तव में इंटरफ़ेस को लागू करता है, जबकि एक सार वर्ग में सामान उन वर्गों के लिए "कोर" है जो वर्ग का विस्तार करते हैं; यानी, यह नहीं बदलता है।
orrymr

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

3
@HiradNikoo देर से टिप्पणी के लिए क्षमा करें, लेकिन मैं सिर्फ इस धागे पर ठोकर खाई। आप क्लास इनहेरिटेंस को आईएस-ए रिलेशनशिप भी मान सकते हैं, जबकि इंटरफेस संकेत देते हैं कि "एक निश्चित कार्यक्षमता है"।
अलेक्जेंडर जंक

206

इस दुनिया में कुछ भी सही नहीं है। वे एक व्यावहारिक दृष्टिकोण की अधिक उम्मीद कर रहे होंगे।

लेकिन आपके स्पष्टीकरण के बाद आप इन पंक्तियों को थोड़ा अलग दृष्टिकोण के साथ जोड़ सकते हैं।

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

  2. इंटरफेस विचार देता है कि क्या किया जाना है लेकिन यह नहीं कि यह कैसे किया जाएगा। इसलिए कार्यान्वयन पूरी तरह से दिए गए नियमों का पालन करके डेवलपर पर निर्भर करता है (इसका मतलब है कि तरीकों का हस्ताक्षर)।

  3. अमूर्त वर्गों में सार घोषणाएं, ठोस कार्यान्वयन या दोनों हो सकते हैं।

  4. सार घोषणाएं नियमों का पालन करने के लिए हैं और ठोस कार्यान्वयन दिशानिर्देशों की तरह हैं (आप इसका उपयोग कर सकते हैं जैसा कि यह है या आप इसे अनदेखा कर सकते हैं और इसे अपना खुद का कार्यान्वयन दे सकते हैं)।

  5. इसके अलावा, जो एक ही हस्ताक्षर के साथ तरीकों को बदल सकते हैं अलग-अलग संदर्भों में व्यवहार को अलग-अलग संदर्भों में तदनुसार लागू करने के लिए नियम के रूप में इंटरफ़ेस घोषणाएं प्रदान की जाती हैं।

संपादित करें: जावा 8 इंटरफ़ेस में डिफ़ॉल्ट और स्थिर तरीकों को परिभाषित करने की सुविधा देता है।

public interface SomeInterfaceOne {

    void usualAbstractMethod(String inputString);

    default void defaultMethod(String inputString){
        System.out.println("Inside SomeInterfaceOne defaultMethod::"+inputString);
    }
}

अब जब कोई वर्ग SomeInterface को लागू करेगा, तो इंटरफ़ेस के डिफ़ॉल्ट तरीकों के लिए कार्यान्वयन प्रदान करना अनिवार्य नहीं है।

यदि हमारे पास निम्नलिखित विधियों के साथ एक और इंटरफ़ेस है:

public interface SomeInterfaceTwo {

    void usualAbstractMethod(String inputString);

    default void defaultMethod(String inputString){
        System.out.println("Inside SomeInterfaceTwo defaultMethod::"+inputString);
    }

}

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

SomeInterfaceOne and SomeInterfaceTwo

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


11
+1, यह भ्रम से बचने के लिए वास्तव में एक अच्छा उत्तर है। लेकिन मुझे कोई लिंक नहीं दिख रहा था और आपको पता नहीं था कि आपने उन मूल्यवान लाइनों को क्यों उद्धृत किया। यदि संभव हो तो उन्हें बिंदुओं के रूप में बनाएं :)।
सुरेश अत्ता

विभिन्न परिवारों के वर्गों के लिए आधार प्रकार होने के लिए इंटरफेस का उपयोग करते हुए और कई इंटरफेस का उपयोग करने के बारे में ऊपर मेरी टिप्पणी पढ़ें। मुझे लगता है कि साक्षात्कारकर्ता साक्षात्कार से उस तरह के उत्तर सुनना चाहता है।
फ्रांसिस्को गोल्डनस्टीन

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

4. ठोस कार्यान्वयन भी नियम हैं, डिफ़ॉल्ट कार्यान्वयन।
लुटेन

@ लुटेन: मेरी जानकारी के अनुसार, यदि आप किसी समस्या के बिना किसी नियम को टाल / अनदेखा कर सकते हैं, तो यह एक नियम नहीं बल्कि एक दिशानिर्देश होना चाहिए। अगर मैं गलत हूं कृपया मुझे सही।
शैलेश सक्सेना

168

आपने उपयोग और कार्यान्वयन में व्यावहारिक अंतरों का एक अच्छा सारांश बनाया लेकिन अर्थ में अंतर के बारे में कुछ नहीं कहा।

एक अंतरफलक व्यवहार का विवरण है जिसे एक कार्यान्वयन वर्ग के पास होगा। कार्यान्वयन वर्ग सुनिश्चित करता है, कि उसके पास ये विधियाँ होंगी जिनका उपयोग उस पर किया जा सकता है। यह मूल रूप से एक अनुबंध या एक वादा है जो वर्ग को करना है।

एक सार वर्ग विभिन्न उपवर्गों के लिए एक आधार है जो व्यवहार को साझा करता है जिसे बार-बार बनाने की आवश्यकता नहीं होती है। उपवर्गों को व्यवहार को पूरा करना होगा और पूर्वनिर्धारित व्यवहार को ओवरराइड करने का विकल्प होना चाहिए (जब तक कि इसे finalया के रूप में परिभाषित नहीं किया जाता है private)।

आपको java.utilपैकेज में अच्छे उदाहरण मिलेंगे जिनमें इंटरफेस जैसी Listऔर अमूर्त कक्षाएं शामिल हैं जैसे AbstractListकि पहले से ही इंटरफ़ेस को लागू करता है। आधिकारिक दस्तावेज का वर्णन AbstractListइस प्रकार है:

यह वर्ग एक "यादृच्छिक अभिगम" डेटा स्टोर (जैसे कि एक सरणी) द्वारा समर्थित इस इंटरफ़ेस को लागू करने के लिए आवश्यक प्रयास को कम करने के लिए सूची इंटरफ़ेस का कंकाल कार्यान्वयन प्रदान करता है।


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

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

85

एक इंटरफ़ेस में सिंगलटन वैरिएबल (सार्वजनिक स्थैतिक अंतिम) और सार्वजनिक अमूर्त विधियाँ हैं। हम आम तौर पर वास्तविक समय में एक इंटरफ़ेस का उपयोग करना पसंद करते हैं जब हम जानते हैं कि क्या करना है लेकिन यह नहीं पता कि यह कैसे करना है

इस अवधारणा को उदाहरण द्वारा बेहतर समझा जा सकता है:

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

public interface Payment
{
    void makePayment();//by default it is a abstract method
}
public class PayPal implements Payment
{
    public void makePayment()
    {
        //some logic for PayPal payment
        //e.g. Paypal uses username and password for payment
    }
}
public class CreditCard implements Payment
{
    public void makePayment()
    {
        //some logic for CreditCard payment
        //e.g. CreditCard uses card number, date of expiry etc...
    }
}

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

हम एक अमूर्त वर्ग का चयन करते हैं जब कुछ विशेषताएं होती हैं जिनके लिए हम जानते हैं कि क्या करना है, और अन्य विशेषताएं जिन्हें हम जानते हैं कि कैसे प्रदर्शन करना है

निम्नलिखित उदाहरण पर विचार करें:

public abstract class Burger
{
    public void packing()
    {
        //some logic for packing a burger
    }
    public abstract void price(); //price is different for different categories of burgers
}
public class VegBerger extends Burger
{
    public void price()
    {
        //set price for a veg burger.
    }
}
public class NonVegBerger extends Burger
{
    public void price()
    {
        //set price for a non-veg burger.
    }
}

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

अन्य अंतर हैं लेकिन ये प्रमुख हैं जो आपके साक्षात्कारकर्ता से उम्मीद कर सकते हैं। उम्मीद है कि यह मददगार था।


1
खैर, यह जवाब बहुत मायने रखता है, और उदाहरण के साथ यह बिल्कुल स्पष्ट है, जब हम बीच का चयन करते हैं interfaceऔर abstract class
मैक

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

45

Abstact वर्ग और इंटरफ़ेस के बीच अंतर

  1. जावा 8 में सार कक्षाएं बनाम इंटरफेस
  2. वैचारिक अंतर:

जावा 8 में इंटरफेस डिफॉल्ट मेथड्स

  1. डिफ़ॉल्ट विधि क्या है?
  2. डिफ़ॉल्ट विधि का उपयोग कर हल किया गया ForEach विधि संकलन त्रुटि
  3. डिफ़ॉल्ट विधि और एकाधिक वंशानुक्रम की समस्याएं
  4. जावा इंटरफ़ेस डिफ़ॉल्ट तरीकों के बारे में महत्वपूर्ण बिंदु:

जावा इंटरफ़ेस स्थैतिक विधि

  1. जावा इंटरफेस स्टेटिक विधि, कोड उदाहरण, स्थिर विधि बनाम डिफ़ॉल्ट विधि
  2. जावा इंटरफेस स्थिर विधि के बारे में महत्वपूर्ण बिंदु:

जावा फंक्शनल इंटरफेस



जावा 8 में सार कक्षाएं बनाम इंटरफेस

जावा 8 इंटरफ़ेस परिवर्तनों में स्थिर तरीके और डिफ़ॉल्ट तरीके शामिल हैं। जावा 8 से पहले, हम इंटरफेस में केवल विधि घोषणाएं कर सकते थे। लेकिन जावा 8 से, हम इंटरफेस में डिफ़ॉल्ट तरीके और स्थिर तरीके रख सकते हैं।

डिफ़ॉल्ट विधि की शुरुआत करने के बाद, ऐसा लगता है कि इंटरफेस और अमूर्त वर्ग समान हैं। हालांकि, वे अभी भी जावा 8 में अलग अवधारणा हैं।

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

वैचारिक अंतर:

सार वर्ग कंकाल (यानी आंशिक) इंटरफेस के कार्यान्वयन के लिए मान्य हैं, लेकिन एक मिलान इंटरफ़ेस के बिना मौजूद नहीं होना चाहिए।

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

जावा 8 में इंटरफेस डिफॉल्ट मेथड्स

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

यह कैसे काम करता है यह समझने के लिए छोटे उदाहरण पर विचार करें:

public interface OldInterface {
    public void existingMethod();
 
    default public void newDefaultMethod() {
        System.out.println("New default method"
               + " is added in interface");
    }
}

निम्न वर्ग जावा JDK 8 में सफलतापूर्वक संकलित करेगा,

public class OldInterfaceImpl implements OldInterface {
    public void existingMethod() {
     // existing implementation is here…
    }
}

यदि आप OldInterfaceImpl का एक उदाहरण बनाते हैं:

OldInterfaceImpl obj = new OldInterfaceImpl ();
// print “New default method add in interface”
obj.newDefaultMethod(); 

डिफ़ॉल्ट विधि:

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

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

डिफ़ॉल्ट तरीके इन इंटरफेस के पुराने कार्यान्वयन को तोड़ने के बिना मौजूदा इंटरफेस में नई कार्यक्षमता जोड़ने में सक्षम हैं।

जब हम एक इंटरफ़ेस का विस्तार करते हैं जिसमें एक डिफ़ॉल्ट विधि होती है, तो हम निम्नलिखित प्रदर्शन कर सकते हैं:

  1. डिफ़ॉल्ट विधि को ओवरराइड न करें और डिफ़ॉल्ट विधि को इनहेरिट करेगा।
  2. उपवर्ग में ओवरराइड की गई अन्य विधियों के समान डिफ़ॉल्ट विधि को ओवरराइड करें।
  3. डिफ़ॉल्ट विधि को अमूर्त के रूप में फिर से परिभाषित करें, जो इसे ओवरराइड करने के लिए उपवर्ग को मजबूर करता है।

डिफ़ॉल्ट विधि का उपयोग कर हल किया गया ForEach विधि संकलन त्रुटि

जावा 8 के लिए, JDK संग्रह बढ़ाया गया है और पूरे संग्रह में विधि जोड़ दी गई है (जो लैम्ब्डा के साथ मिलकर काम करती है)। पारंपरिक तरीके से, कोड नीचे की तरह दिखता है,

public interface Iterable<T> {
    public void forEach(Consumer<? super T> consumer);
}

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

डिफ़ॉल्ट विधि के साथ Iterable इंटरफ़ेस नीचे है,

public interface Iterable<T> {
    public default void forEach(Consumer
                   <? super T> consumer) {
        for (T t : this) {
            consumer.accept(t);
        }
    }
}

कार्यान्वयन तंत्रों को तोड़े बिना JDK इंटरफ़ेस में स्ट्रीम जोड़ने के लिए समान तंत्र का उपयोग किया गया है ।


डिफ़ॉल्ट विधि और एकाधिक वंशानुक्रम की समस्याएं

चूंकि जावा क्लास कई इंटरफेस को लागू कर सकता है और प्रत्येक इंटरफ़ेस एक ही विधि हस्ताक्षर के साथ डिफ़ॉल्ट विधि को परिभाषित कर सकता है, इसलिए, विरासत में मिली विधियां एक दूसरे के साथ संघर्ष कर सकती हैं।

उदाहरण के नीचे विचार करें,

public interface InterfaceA {  
       default void defaultMethod(){  
           System.out.println("Interface A default method");  
    }  
}
 
public interface InterfaceB {
   default void defaultMethod(){
       System.out.println("Interface B default method");
   }
}
 
public class Impl implements InterfaceA, InterfaceB  {
}

उपरोक्त कोड निम्नलिखित त्रुटि के साथ संकलित करने में विफल रहेगा,

java: class Impl को डिफॉल्टमैथोड () प्रकार के इंटरफेसए और इंटरफेसबी के लिए असंबंधित चूक मिली

इस वर्ग को ठीक करने के लिए, हमें डिफ़ॉल्ट विधि लागू करने की आवश्यकता है:

public class Impl implements InterfaceA, InterfaceB {
    public void defaultMethod(){
    }
}

इसके अलावा, यदि हम अपने स्वयं के कार्यान्वयन के बजाय किसी भी सुपर इंटरफ़ेस द्वारा प्रदान की गई डिफ़ॉल्ट कार्यान्वयन को लागू करना चाहते हैं, तो हम निम्नानुसार कर सकते हैं,

public class Impl implements InterfaceA, InterfaceB {
    public void defaultMethod(){
        // existing code here..
        InterfaceA.super.defaultMethod();
    }
}

हम अपनी नई विधि के हिस्से के रूप में किसी भी डिफ़ॉल्ट कार्यान्वयन या दोनों का चयन कर सकते हैं।

जावा इंटरफ़ेस डिफ़ॉल्ट तरीकों के बारे में महत्वपूर्ण बिंदु:

  1. जावा इंटरफ़ेस डिफ़ॉल्ट तरीके कार्यान्वयन कक्षाओं को तोड़ने के डर के बिना इंटरफेस को विस्तारित करने में हमारी मदद करेंगे।
  2. जावा इंटरफ़ेस डिफ़ॉल्ट तरीकों ने इंटरफेस और अमूर्त वर्गों के बीच अंतर को कम कर दिया है।
  3. जावा 8 इंटरफ़ेस डिफ़ॉल्ट तरीके उपयोगिता कक्षाओं से बचने में हमारी मदद करेंगे, जैसे कि सभी कलेक्शन क्लास पद्धति को इंटरफेस में ही प्रदान किया जा सकता है।
  4. जावा इंटरफ़ेस डिफ़ॉल्ट तरीके आधार कार्यान्वयन कक्षाओं को हटाने में हमारी मदद करेंगे, हम डिफ़ॉल्ट कार्यान्वयन प्रदान कर सकते हैं और कार्यान्वयन कक्षाएं चुन सकते हैं कि कौन सा ओवरराइड करना है।
  5. इंटरफेस में डिफ़ॉल्ट तरीकों को पेश करने का एक बड़ा कारण लैम्बडा एक्सप्रेशन को सपोर्ट करने के लिए जावा 8 में कलेक्शंस एपीआई को बढ़ाना है।
  6. यदि पदानुक्रम में किसी भी वर्ग के पास एक ही हस्ताक्षर के साथ एक विधि है, तो डिफ़ॉल्ट तरीके अप्रासंगिक हो जाते हैं। एक डिफ़ॉल्ट विधि java.lang.Object से एक विधि को ओवरराइड नहीं कर सकती है। तर्क बहुत सरल है, यह इसलिए है क्योंकि ऑब्जेक्ट सभी जावा कक्षाओं के लिए आधार वर्ग है। इसलिए भले ही हमारे पास ऑब्जेक्ट क्लास मेथड्स को इंटरफेस में डिफ़ॉल्ट तरीकों के रूप में परिभाषित किया गया है, यह बेकार होगा क्योंकि ऑब्जेक्ट क्लास पद्धति हमेशा उपयोग की जाएगी। इसीलिए भ्रम से बचने के लिए, हमारे पास डिफ़ॉल्ट तरीके नहीं हो सकते हैं जो ऑब्जेक्ट क्लास विधियों को ओवरराइड कर रहे हैं।
  7. जावा इंटरफ़ेस डिफ़ॉल्ट तरीकों को डिफेंडर विधियों या वर्चुअल एक्सटेंशन विधियों के रूप में भी संदर्भित किया जाता है।

संसाधन लिंक:

  1. जावा 8 में डिफॉल्ट तरीकों बनाम सार वर्ग के साथ इंटरफ़ेस
  2. जेडीके 8 युग में सार वर्ग बनाम इंटरफ़ेस
  3. आभासी विस्तार विधियों के माध्यम से इंटरफ़ेस विकास

जावा इंटरफ़ेस स्थैतिक विधि

जावा इंटरफेस स्टेटिक विधि, कोड उदाहरण, स्थिर विधि बनाम डिफ़ॉल्ट विधि

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

public interface MyData {

    default void print(String str) {
        if (!isNull(str))
            System.out.println("MyData Print::" + str);
    }

    static boolean isNull(String str) {
        System.out.println("Interface Null Check");

        return str == null ? true : "".equals(str) ? true : false;
    }
}

अब आइए एक कार्यान्वयन वर्ग देखें जो खराब कार्यान्वयन के साथ नल () विधि है।

public class MyDataImpl implements MyData {

    public boolean isNull(String str) {
        System.out.println("Impl Null Check");

        return str == null ? true : false;
    }

    public static void main(String args[]){
        MyDataImpl obj = new MyDataImpl();
        obj.print("");
        obj.isNull("abc");
    }
}

ध्यान दें कि Null (String str) एक सरल वर्ग विधि है, यह इंटरफ़ेस विधि को ओवरराइड नहीं कर रही है। उदाहरण के लिए, यदि हम isNull () विधि में @Override एनोटेशन जोड़ देंगे, तो इसका परिणाम संकलक त्रुटि के रूप में होगा।

अब जब हम एप्लिकेशन चलाएंगे, तो हमें आउटपुट मिल जाएगा।

इंटरफ़ेस नल की जाँच करें

Impl Null Check

यदि हम इंटरफ़ेस विधि को स्थैतिक से डिफ़ॉल्ट बनाते हैं, तो हमें निम्न आउटपुट मिलेंगे।

Impl Null Check

MyData प्रिंट ::

Impl Null Check

जावा इंटरफ़ेस स्थिर विधि केवल इंटरफ़ेस विधियों के लिए दृश्यमान है, यदि हम MyDataImpl वर्ग से isNull () विधि को हटाते हैं, तो हम इसे MyDataImpl ऑब्जेक्ट के लिए उपयोग नहीं कर पाएंगे। हालाँकि अन्य स्थैतिक तरीकों की तरह, हम क्लास नाम का उपयोग करके इंटरफ़ेस स्टैटिक विधियों का उपयोग कर सकते हैं। उदाहरण के लिए, एक मान्य कथन होगा:

boolean result = MyData.isNull("abc");

जावा इंटरफेस स्थिर विधि के बारे में महत्वपूर्ण बिंदु:

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

जावा फंक्शनल इंटरफेस

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

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

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

संसाधन स्थान:

  1. जावा 8 इंटरफ़ेस परिवर्तन - स्थिर विधि, डिफ़ॉल्ट विधि

8
मैं इस प्रकार के अद्यतन उत्तरों की तलाश में हूँ। तुरंत जवाब के लिए धन्यवाद।
रवींद्र बाबू

41

आपके सभी कथन आपके पहले बयान (जावा 8 रिलीज के बाद) को छोड़कर मान्य हैं:

एक जावा इंटरफेस के तरीके स्पष्ट रूप से सार हैं और कार्यान्वयन नहीं हो सकते हैं

प्रलेखन पृष्ठ से :

एक इंटरफ़ेस एक संदर्भ प्रकार है, एक वर्ग के समान है, जिसमें केवल स्थिरांक, विधि हस्ताक्षर, डिफ़ॉल्ट विधियाँ, स्थैतिक विधियाँ, और नेस्टेड प्रकार हो सकते हैं

विधि निकाय केवल डिफ़ॉल्ट विधियों और स्थिर विधियों के लिए मौजूद हैं।

डिफ़ॉल्ट विधियाँ:

एक इंटरफ़ेस में डिफ़ॉल्ट विधियाँ हो सकती हैं , लेकिन अमूर्त कक्षाओं में अमूर्त विधियों की तुलना में अलग हैं।

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

जब आप एक इंटरफ़ेस का विस्तार करते हैं जिसमें एक डिफ़ॉल्ट विधि होती है, तो आप निम्न कार्य कर सकते हैं:

  1. डिफ़ॉल्ट विधि का बिल्कुल भी उल्लेख न करें, जो आपके विस्तारित इंटरफ़ेस को डिफ़ॉल्ट विधि का वारिस बनाती है।
  2. डिफ़ॉल्ट विधि को फिर से घोषित करें, जो इसे बनाता है abstract
  3. डिफ़ॉल्ट विधि को फिर से परिभाषित करें, जो इसे ओवरराइड करता है।

स्थैतिक तरीके:

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

इससे आपके पुस्तकालयों में सहायक विधियों को व्यवस्थित करना आपके लिए आसान हो जाता है;

interfaceहोने staticऔर defaultविधियों के बारे में प्रलेखन पृष्ठ से उदाहरण कोड ।

import java.time.*;

public interface TimeClient {
    void setTime(int hour, int minute, int second);
    void setDate(int day, int month, int year);
    void setDateAndTime(int day, int month, int year,
                               int hour, int minute, int second);
    LocalDateTime getLocalDateTime();

    static ZoneId getZoneId (String zoneString) {
        try {
            return ZoneId.of(zoneString);
        } catch (DateTimeException e) {
            System.err.println("Invalid time zone: " + zoneString +
                "; using default time zone instead.");
            return ZoneId.systemDefault();
        }
    }

    default ZonedDateTime getZonedDateTime(String zoneString) {
        return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
    }
}

एक इंटरफ़ेस या अमूर्त वर्ग का उपयोग करने के लिए चुने गए दिशा निर्देशों का उपयोग करें।

इंटरफेस:

  1. एक अनुबंध को परिभाषित करने के लिए (अधिमानतः स्टेटलेस - मेरा मतलब है कि कोई चर नहीं)
  2. असंबंधित कक्षाएं लिंक करने के लिए के साथ एक है क्षमताओं।
  3. सार्वजनिक निरंतर चर ( अपरिवर्तनीय स्थिति ) घोषित करने के लिए

सार वर्ग:

  1. कई करीबी संबंधित वर्गों के बीच कोड साझा करें। यह एक संबंध है।

  2. संबंधित वर्गों के बीच साझा राज्य (कंक्रीट कक्षाओं में राज्य को संशोधित किया जा सकता है)

संबंधित पोस्ट:

इंटरफ़ेस बनाम सार वर्ग (सामान्य ऊ)

इम्प्लीमेंट्स बनाम विस्तार: कब उपयोग करें? क्या फर्क पड़ता है?

इन उदाहरणों से गुजरकर, आप समझ सकते हैं

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


"स्टेटलेस कॉन्ट्रैक्ट" कहने का क्या मतलब है? यह इंटरफेस 1 के बारे में आइटम 1 है
दिमित्री

1
परिवर्तनशील अवस्था की अनुपस्थिति। चूँकि इंटरफ़ेस में स्थिरांक हो सकते हैं, डेटा को अमूर्त वर्गों के विपरीत उत्परिवर्तित किया जा सकता है
रविन्द्र बाबू

1
उपरोक्त कथन में सुधार। इंटरफ़ेस में, डेटा को अमूर्त वर्ग के विपरीत उत्परिवर्तित नहीं किया जा सकता है
रवींद्र बाबू

2
यह सबसे अच्छा जवाब है। यह न केवल Java8 को संबोधित करता है, बल्कि यह भी बताता है कि आप किन विशेष परिस्थितियों में किसी एक का उपयोग करेंगे।
शुकलस्वाग २

statelessइंटरफ़ेस की अवधारणा एक अच्छी हिट है। इंटरफ़ेस में कोई स्थिति नहीं हो सकती है (इंटरफ़ेस में स्थिरांक हो सकते हैं लेकिन वे अंतिम / स्थिर हैं और इस प्रकार अपरिवर्तनीय हैं)।
काहुआ

22

आपकी व्याख्या सभ्य दिखती है, लेकिन क्या ऐसा लग सकता है कि आप यह सब किसी पाठ्यपुस्तक से पढ़ रहे थे? : - /

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

व्यक्तिगत रूप से, मैं इस लिंक का सुझाव दूंगा : http://mindprod.com/jgloss/interfacevsabstract.html#TABLE

मतभेदों की एक विस्तृत सूची के लिए ..

आशा है कि यह आपके और सभी पाठकों को उनके भविष्य के साक्षात्कार में मदद करेगा


1
लिंक साझा किया गया वास्तव में बहुत बढ़िया है
प्रेमराज

आप डिफ़ॉल्ट कीवर्ड का उपयोग करके जावा इंटरफेस में डिफ़ॉल्ट कार्यान्वयन प्रदान कर सकते हैं
ओगेन

21

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

इंटरफेस और अमूर्त वर्ग, हालांकि एक तकनीकी दृष्टिकोण से समान रूप से समान है, इसके पूरी तरह से अलग अर्थ और उद्देश्य हैं।

सारांश

  1. एक इंटरफेस एक अनुबंध को परिभाषित करता है कि कुछ कार्यान्वयन पूरा करेगा आप के लिए

  2. एक अमूर्त वर्ग एक डिफ़ॉल्ट व्यवहार प्रदान करता है जिसे आपका कार्यान्वयन पुन: उपयोग कर सकता है।

ऊपर इन दो बिंदुओं को मैं साक्षात्कार के समय देख रहा हूं, और एक कॉम्पैक्ट पर्याप्त सारांश है। अधिक जानकारी के लिए पढ़ें।

वैकल्पिक सारांश

  1. एक इंटरफ़ेस सार्वजनिक एपीआई को परिभाषित करने के लिए है
  2. एक सार वर्ग आंतरिक उपयोग के लिए है, और एसपीआई को परिभाषित करने के लिए है

उदाहरण द्वारा

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

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

एक अमूर्त वर्ग इंटरफेस और कंक्रीट कक्षाओं के बीच में है। यह कार्यान्वयन को साझा या बोरिंग कोड को साझा करने में मदद करने वाला है। उदाहरण के लिए, आकार के आधार पर AbstractCollectionमूल कार्यान्वयन प्रदान करता isEmptyहै 0, containsपुनरावृति के addAllरूप में , तुलना की जाती है, दोहराया जाता है add, और इसी तरह। यह कार्यान्वयन को उन महत्वपूर्ण भागों पर ध्यान केंद्रित करने देता है जो उनके बीच अंतर करते हैं: वास्तव में डेटा को कैसे संग्रहीत और पुनर्प्राप्त करें।

एक और परिप्रेक्ष्य: एपीआई बनाम एसपीआई

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

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

एक एपीआई और एक एसपीआई के बीच अंतर सूक्ष्म, लेकिन महत्वपूर्ण है: एक एपीआई के लिए, ध्यान केंद्रित है कि कौन इसका उपयोग करता है, और एक एसपीआई के लिए ध्यान उस पर है जो इसे लागू करता है।

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

जावा 8 और डिफ़ॉल्ट विधियों पर एक नोट

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

"किताबी ज्ञान"

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

यहाँ एक सादृश्य है: माना जाता था कि प्रश्न था:

प्रोम रात, कार या होटल के कमरे के लिए किराए पर लेना बेहतर है?

तकनीकी उत्तर ऐसा लगता है:

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

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


क्या आपका मतलब "कम-युग्मन" था?
user2418306

@ user2418306 नहीं, सामंजस्य एक अधिक सामान्य शब्द है जिसमें युग्मन शामिल है, हालांकि वे करीब समानार्थी शब्द हैं, और या तो शब्द ने काम किया होगा।
सेर्गी डुमित्रियू

9

निम्नलिखित तरीके से सोचने के बारे में:

  • एक वर्ग और एक अमूर्त वर्ग के बीच का संबंध "is-a" है
  • एक वर्ग और एक अंतरफलक के बीच का संबंध "has-a" प्रकार का है

इसलिए जब आपके पास एक सार वर्ग स्तनधारी, एक उपवर्ग मानव और एक इंटरफ़ेस ड्राइविंग है, तो आप कह सकते हैं

  • प्रत्येक मानव एक स्तनधारी है
  • प्रत्येक मानव के पास एक ड्राइविंग (व्यवहार) है

मेरा सुझाव यह है कि पुस्तक ज्ञान वाक्यांश इंगित करता है कि वह दोनों के बीच शब्दार्थ अंतर को सुनना चाहता था (जैसे कि यहां पहले से ही सुझाए गए अन्य)।


9

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

package adventure;
import java.awt.*;
public interface Playable {
    public void playSound(String s);
    public Image loadPicture(String s);    
}

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

public class Adventure extends JFrame implements Playable

public class Dungeon3D extends SimpleApplication implements Playable

public class Main extends SimpleApplication implements AnimEventListener, ActionListener, Playable

आमतौर पर, गेमवर्ल्ड में, दुनिया एक अमूर्त वर्ग हो सकती है जो खेल पर तरीकों का प्रदर्शन करती है:

public abstract class World...

    public Playable owner;

    public Playable getOwner() {
        return owner;
    }

    public void setOwner(Playable owner) {
        this.owner = owner;
    }

6

अमूर्त वर्ग शुद्ध अमूर्त नहीं हैं (कंक्रीट के कार्यान्वित तरीकों) के संग्रह के साथ-साथ अनिमित तरीके भी। लेकिन इंटरफेस शुद्ध अमूर्त bcz हैं केवल ठोस तरीके नहीं लागू किए गए तरीके हैं।

सार वर्ग क्यों?

  1. यदि उपयोगकर्ता सभी वस्तुओं के लिए सामान्य कार्यक्षमता लिखना चाहता है।
  2. भविष्य में पुन: कार्यान्वयन के लिए सार कक्षाएं सबसे अच्छा विकल्प हैं जो अंत उपयोगकर्ता को प्रभावित किए बिना अधिक कार्यक्षमता जोड़ते हैं।

क्यों इंटरफेस?

  1. यदि उपयोगकर्ता अलग-अलग कार्यक्षमता लिखना चाहता है जो वस्तुओं पर अलग-अलग कार्यक्षमता होगी।
  2. इंटरफेस सबसे अच्छा विकल्प है कि अगर इंटरफ़ेस प्रकाशित होने के बाद आवश्यकताओं को संशोधित करने की आवश्यकता नहीं है।

5

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

एक अमूर्त वर्ग एकल-सेक्स प्रजातियों (*) के मृत पूर्वज की तरह है : उसे जीवन में नहीं लाया जा सकता है लेकिन एक जीवित (यानी गैर-सार ) वंशज उसके सभी जीनों को विरासत में मिला है।

(*) इस रूपक को फैलाने के लिए, आइए हम कहते हैं कि प्रजातियों के सभी सदस्य एक ही उम्र में रहते हैं। इसका मतलब है कि मृत पूर्वज के सभी पूर्वजों को भी मृत होना चाहिए - और इसी तरह, एक जीवित पूर्वज के सभी वंशज जीवित होना चाहिए।


4

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

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

भविष्य में साक्षात्कार के साथ शुभकामनाएँ।

इस सवाल का मेरा जवाब भी तकनीकी सामग्री जो आपने प्रदान की है, उसके बजाय साक्षात्कार तकनीक के बारे में अधिक है। शायद इसके बारे में पढ़ने पर विचार करें। https://workplace.stackexchange.com/ इस तरह की चीज़ के लिए एक उत्कृष्ट स्थान हो सकता है।


1
क्या आप मुझे बता सकते हैं कि आपने इसका उत्तर कैसे दिया? हो सकता है यह मेरी मदद कर सकता है।
code_fish

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

4

आप कई उत्तराधिकार में डायमंड समस्या से बचने के लिए जावा में इंटरफ़ेस चुनते हैं ।

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

यदि आप पहले से ही जानते हैं कि आप अमूर्त वर्ग का चयन करते हैं। उदाहरण के लिए एक सार वर्ग लें Car। उच्च स्तर पर आप सामान्य कार विधियों को लागू करते हैं, जैसे calculateRPM()। यह एक सामान्य तरीका है और आप ग्राहक को अपने व्यवहार जैसे
calculateMaxSpeed()आदि को लागू करने देते हैं । संभवतः आपने कुछ वास्तविक समय के उदाहरण देकर समझाया होगा जो आपने अपने दिन में नौकरी के लिए सामना किया है।


3

एक इंटरफ़ेस विशुद्ध रूप से सार है। हमारे पास इंटरफ़ेस में कोई कार्यान्वयन कोड नहीं है।

अमूर्त वर्ग में विधियाँ और उसका कार्यान्वयन दोनों शामिल हैं।

इंटरफेस और अमूर्त कक्षाओं पर ट्यूटोरियल देखने के लिए यहां क्लिक करें


3

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


3

यहां तक ​​कि मैंने कई साक्षात्कारों में एक ही सवाल का सामना किया है और मेरा मानना ​​है कि यह साक्षात्कारकर्ता को समझाने के लिए आपके समय को दुखी करता है। अगर मुझे ऊपर से सभी उत्तर निहित हैं तो मुझे एक और महत्वपूर्ण बिंदु जोड़ने की जरूरत है ताकि इसे और अधिक ठोस बनाया जा सके और OO को इसके सर्वोत्तम उपयोग में लाया जा सके।

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

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

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


2

जब मैं 2 करीबी संबंधित कक्षाओं के बीच व्यवहार साझा करने की कोशिश कर रहा हूं, तो मैं एक अमूर्त वर्ग बनाता हूं जो सामान्य व्यवहार रखता है और दोनों वर्गों के लिए माता-पिता के रूप में कार्य करता है।

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

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

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

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


2

इंटरफ़ेस और अमूर्त वर्ग के बीच बुनियादी अंतर है, इंटरफ़ेस एकाधिक वंशानुक्रम का समर्थन करता है लेकिन सार वर्ग नहीं।

अमूर्त वर्ग में भी आप इंटरफ़ेस जैसे सभी सार तरीके प्रदान कर सकते हैं।

अमूर्त वर्ग की आवश्यकता क्यों है?

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

इंटरफ़ेस की आवश्यकता क्यों है?

मान लीजिए, मेरे पास एक काम है, जिसका मुझे उस क्षेत्र में अनुभव नहीं है। उदाहरण के लिए, यदि आप एक इमारत या बांध बनाना चाहते हैं, तो आप उस परिदृश्य में क्या करेंगे?

  1. आप पहचान लेंगे कि आपकी क्या आवश्यकताएं हैं और उस आवश्यकताओं के साथ एक अनुबंध करें।
  2. फिर अपनी परियोजना के निर्माण के लिए निविदाओं को बुलाएं
  3. जो कभी भी परियोजना का निर्माण करते हैं, उन्हें आपकी आवश्यकताओं को पूरा करना चाहिए। लेकिन निर्माण तर्क एक विक्रेता से दूसरे विक्रेता के लिए अलग है।

यहाँ मैं तर्क के बारे में परेशान नहीं हूँ कि उन्होंने कैसे निर्माण किया। अंतिम वस्तु ने मेरी आवश्यकताओं को पूरा किया या नहीं, केवल मेरी महत्वपूर्ण बात।

यहां आपकी आवश्यकताओं को इंटरफ़ेस और कंस्ट्रक्टर्स को कार्यान्वयनकर्ता कहा जाता है।


2

कुछ शब्दों में, मैं इस तरह से उत्तर दूंगा:

  • श्रेणी पदानुक्रम के माध्यम से विरासत एक राज्य विरासत का मतलब है ;
  • जबकि इंटरफेस के माध्यम से विरासत व्यवहार विरासत के लिए खड़ा है ;

इन दो मामलों के बीच सार कक्षाओं को कुछ के रूप में माना जा सकता है (यह कुछ राज्य का परिचय देता है, लेकिन व्यवहार को परिभाषित करने के लिए आपको बाध्य भी करता है), एक पूरी तरह से अमूर्त वर्ग एक इंटरफ़ेस है (यह कक्षाओं का एक और विकास है, जो केवल C ++ में आभासी तरीकों से मिलकर बनता है) जहाँ तक मुझे इसके सिंटैक्स के बारे में पता है)।

बेशक, जावा 8 से शुरू होकर चीजें थोड़ी बदल गईं, लेकिन विचार अभी भी वही है।

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


1

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


1

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


1

हां, आपकी प्रतिक्रियाएं तकनीकी रूप से सही थीं लेकिन जहां आप गलत थे, उन्हें नहीं दिखा रहा था कि आप एक-दूसरे को चुनने के उतार-चढ़ाव को समझते हैं। इसके अतिरिक्त, वे संभवतः चिंतित थे / भविष्य में उन्नयन के साथ अपने कोडबेस की संगतता के बारे में पता चला। इस प्रकार की प्रतिक्रिया ने मदद की हो सकती है (आपने जो कहा उसके अलावा):

"इंटरफ़ेस क्लास पर एक सार वर्ग का चयन करना इस बात पर निर्भर करता है कि हम कोड के भविष्य को क्या प्रोजेक्ट करते हैं।

एब्सट्रैक्ट क्लासेस बेहतर फॉरवर्ड-कम्पैटिबिलिटी की अनुमति देते हैं क्योंकि आप अपने मौजूदा कोड को तोड़े बिना एब्सट्रैक्ट क्लास को भविष्य में अच्छी तरह से जोड़ना जारी रख सकते हैं -> यह इंटरफ़ेस क्लास के साथ संभव नहीं है।

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

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

आपके अगले साक्षात्कार पर शुभकामनाएँ!


1

मैं दोनों के बीच अंतर दिखाने के लिए व्यावहारिक परिदृश्य का उपयोग करके जवाब देने की कोशिश करूंगा।

रिक्त स्थान शून्य पेलोड के साथ आते हैं अर्थात किसी भी राज्य को बनाए नहीं रखा जाता है और इस तरह एक वर्ग के साथ एक अनुबंध (क्षमता) को जोड़ने के लिए बेहतर विकल्प होता है।

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

अब आप पूछ सकते हैं कि क्या रननेबल एक सार वर्ग था?

अच्छी तरह से तकनीकी रूप से यह संभव था लेकिन डिजाइन के हिसाब से यह एक खराब विकल्प था:

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

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

बस हमें एक क्षमता (अनुबंध) को परिभाषित करने के लिए इंटरफ़ेस डालें, जबकि कंकाल (आम / आंशिक) के कार्यान्वयन को परिभाषित करने के लिए एक सार वर्ग का उपयोग करें।

डिस्क्लेमर: मूर्खतापूर्ण उदाहरण निम्नानुसार है, न्याय न करने का प्रयास करें :-P

interface Forgiver {
    void forgive();
}

abstract class GodLike implements Forgiver {
    abstract void forget();
    final void forgive() {
        forget();
    }
}

अब आपको GodLike होने का विकल्प दिया गया है लेकिन आप केवल Forgiver होना चुन सकते हैं (अर्थात GodLike नहीं) और करें:

class HumanLike implements Forgiver {
    void forgive() {
       // forgive but remember    
    }
}

या आप GodLike होना और करना चुन सकते हैं:

class AngelLike extends GodLike {
    void forget() {
       // forget to forgive     
    }
}

जावा 8 इंटरफ़ेस के साथ PS में स्थैतिक के साथ-साथ डिफ़ॉल्ट (अधिक उपयोग योग्य कार्यान्वयन) विधियाँ भी हो सकती हैं और इस प्रकार अंतर b / w इंटरफ़ेस और अमूर्त वर्ग और भी अधिक संकुचित हो जाता है।


1

लगभग सब कुछ पहले से ही यहाँ कवर किया गया लगता है .. abstractवर्ग के व्यावहारिक कार्यान्वयन पर सिर्फ एक और बिंदु जोड़ना :

abstractकीवर्ड का उपयोग सिर्फ क्लास को तुरंत करने से रोकने के लिए भी किया जाता है। यदि आपके पास एक ठोस वर्ग है जिसे आप तुरंत नहीं बनाना चाहते हैं - इसे बनाओ abstract


1

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

अपना उत्तर समाप्त करने के बाद आपको उदाहरण पर कूदना चाहिए:

सार:

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

public abstract class CTC {

    public int salary(int hra, int da, int extra)
    {
        int total;
        total = hra+da+extra;
        //incentive for specific performing employee
        //total = hra+da+extra+incentive;
        return total;
    }
}

class Manger extends CTC
{
}


class CEO extends CTC
{
}

class Developer extends CTC
{   
}

इंटरफेस

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

public interface EmployeType {

    public String typeOfEmployee();
}

class ContarctOne implements EmployeType
{

    @Override
    public String typeOfEmployee() {
        return "contract";
    }

}

class PermanentOne implements EmployeType
{

    @Override
    public String typeOfEmployee() {
        return "permanent";
    }

}

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


1

मैं जो समझता हूं और मैं कैसे दृष्टिकोण करता हूं,

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

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

नोट: जब तक विधि स्थिर या डिफ़ॉल्ट नहीं होती है, तब तक आप इंटरफ़ेस विधियों में फ़ंक्शन बॉडी नहीं रख सकते।


0

मेरा मानना ​​है कि साक्षात्कारकर्ता जो पाने की कोशिश कर रहा था, वह शायद इंटरफ़ेस और कार्यान्वयन के बीच का अंतर था।

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

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

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

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


0

आपका उत्तर सही है लेकिन साक्षात्कारकर्ता को आपको सॉफ्टवेयर इंजीनियरिंग के दृष्टिकोण के अनुसार अंतर करने की आवश्यकता है न कि जावा के विवरण के अनुसार।

आसान शब्द:

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

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