2011-12-07 1 views
12

यदि हम किसी ऑब्जेक्ट को किसी इंटरफ़ेस पर डालेंगे, तो क्या यह ऑब्जेक्ट अपनी विधियों को कॉल करने में सक्षम नहीं होगा? निम्नलिखित उदाहरण में, myObj केवल MyInterface विधियों को कॉल करने में सक्षम होगा?जावा में एक इंटरफेस के लिए एक वस्तु डाली?

MyInterface myObj = new Obj(); 

यदि यह सही है, क्या उन 2 वस्तुओं के बीच अंतर है:

MyInterface myObj = new Obj(); 

MyInterface mySec = new Sec(); 

आपकी मदद

+0

[यह] (http://docs.oracle.com/javase/tutorial/java/concepts/interface.html) मदद की हो सकती है। – Nerdtron

उत्तर

16
MyInterface myObj = new Obj(); 
MyInterface mySec = new Sec(); 

इस कानूनी होने के लिए के लिए धन्यवाद, दोनों Obj और Sec होगा MyInterface के कार्यान्वयनकर्ता होना चाहिए। इन दो वस्तुओं के बीच का अंतर होगा वे कार्यान्वयन प्रदान करते हैं। Obj और Sec दो बहुत ही अलग या बहुत समान चीजें कर सकता है, लेकिन उनकी समानता यह है कि वे उस अनुबंध का पालन करेंगे जिस पर आप भरोसा कर सकते हैं। यदि आप एक विधि

public void doSomethingWith(MyInterface thing) { 
    thing.frob(); 
} 

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

लेकिन मैं भी पढ़ा है कि अगर हम MyInterface के रूप में वस्तु myObj घोषित, myObj (कक्षा Obj से) अपने स्वयं के तरीकों का इस्तेमाल करने में सक्षम नहीं होगा, है, जिसे ठीक

आंतरिक , Obj के उदाहरणों को Obj API पर पूर्ण पहुंच जारी रहेगी। myObj अभी भी एक Obj है, यह हमेशा अपने कार्यान्वयन के विवरण का उपयोग करने में सक्षम होगा।

public interface MyInterface { 
    void frob(); 
} 

public class Obj implements MyInterface { 

    public void frob() { 
     doFrobbing(); 
    } 

    private void doFrobbing() { 
     System.out.println("frobbing"); 
    } 

    public static void main(String[] args) { 
     MyInterface myObj = new Obj(); 
     myObj.frob(); // still internally calls doFrobbing() 
     ((Obj)myObj).doFrobbing(); // visible only via class reference 
    } 
} 

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

+0

इस महान स्पष्टीकरण के लिए धन्यवाद एंथनी, मैं इसे समझता हूं, और अब और भी धन्यवाद, लेकिन मैंने यह भी पढ़ा है कि अगर हम ऑब्जेक्ट 'myObj' को MyInterface के रूप में घोषित करते हैं, तो 'myObj' अपने तरीकों का उपयोग करने में सक्षम नहीं होगा (से वर्ग 'ओब्ज'), क्या यह सही है? – Paul

+0

@ पॉल, अच्छा सवाल, उत्तर अपडेट किया गया। –

+0

अद्यतन के लिए धन्यवाद, तो यह करने का क्या मतलब है? ('MyInterface' प्रकार है जब' Obj' के तरीकों को छुपाएं) किसी ऑब्जेक्ट में कुछ विधियों को "जोड़ने" के लिए एक इंटरफेस "मौजूद" है, है ना? तो यह अन्य तरीकों को क्यों छिपाता है? (या शायद इसके लिए कोई कारण नहीं है, यह काम करता है क्योंकि, प्रत्येक प्रोग्रामिंग भाषा में एक सामान्य नियम के रूप में, एक "प्रकार" ऐसा काम करता है?) – Paul

1

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

public interface MyInterface { 
    String getName(); 
} 

public class Obj implements MyInterface { 
    private String getFirstName() { 
     return "John"; 
    } 

    private String getLastName() { 
     return "Doe"; 
    } 

    @Override 
    public String getName() { 
     return getFirstName() + " " + getLastName(); 
    } 
} 

public class Sec implements MyInterface { 
    private String getDate() { 
     return new Date().toString(); 
    } 

    @Override 
    public String getName() { 
     return getDate(); 
    } 
} 

ऊपर मामलों में, दोनों Obj और Sec उनके निजी सदस्यों कॉल कर सकते हैं, भले ही वे अन्य वर्गों में नहीं दिखाई देंगे। तो जब आप कहते हैं ...

MyInterface myObj = new Obj(); 
MyInterface mySec = new Sec(); 

...जैसा कि आपने सवाल में पूछा है, जबकि यह सच है कि myObj और mySec में केवल एक ही विधि दिखाई देने वाली विधि getName() है, उनका अंतर्निहित कार्यान्वयन अलग-अलग हो सकता है।

+0

धन्यवाद इस महान स्पष्टीकरण के लिए जोनाथन, एमएमएच, ठीक है, मैं इसे थोड़ा और समझता हूं, इसलिए अगर अन्य वर्गों द्वारा 'ओब्ज' के तरीके दिखाई नहीं दे रहे हैं, तो इस मामले में क्या मायने रखता है? (क्या आपके पास एक साधारण उदाहरण है?) – Paul

+0

क्षमा करें, मुझे यकीन नहीं है कि मैं आपका प्रश्न समझता हूं। –

1

कोई फर्क नहीं पड़ता। आप केवल MyInterfacemyObj और mySec पर इंटरफ़ेस विधियों का आह्वान करने में सक्षम होंगे। जाहिर है कि आपका कोड केवल संकलित होगा यदि Obj और Sec दोनों Myinterface इंटरफ़ेस को लागू करते हैं।

+0

आपके त्वरित उत्तर के लिए धन्यवाद, तो यहां बात है: क्या होगा अगर हमने इंटरफेस के बिना परियोजना शुरू की, और फिर हम एक इंटरफ़ेस को कार्यान्वित करना चाहते हैं क्योंकि हमें कक्षाओं 'ए' और 'बी' पर जोड़े जाने के लिए और अधिक तरीकों की आवश्यकता है: हम हार जाएंगे 'ए' और 'बी' से पिछली विधियां क्योंकि हम 'ए' और' बी 'घोषित करेंगे क्योंकि मैं ऑब्जेक्ट्स ... – Paul

+0

@ पॉल इंटरफेस कुछ सामान्य * इंटरफ़ेस * (या दूसरे शब्दों में अनुबंध जोड़ने के उद्देश्य से मौजूद है)) विभिन्न वर्गों के लिए और उन कक्षाओं को वास्तव में अनुबंध के अनुसार * कार्यक्षमता * लागू करने देते हैं। यदि आप कक्षा में नई विधियां जोड़ना चाहते हैं तो आपको वास्तव में इंटरफेस का उपयोग करने की आवश्यकता नहीं है। इंटरफ़ेस क्या है इसकी एक सादा परिभाषा यहां दी गई है: http://docs.oracle.com/javase/tutorial/java/concepts/interface.html – Strelok

+0

धन्यवाद Strelok, मेरी गलतफहमी किसी ऑब्जेक्ट के "प्रकार" को बदलने के बारे में है, और इंटरफेस को "टाइप" के रूप में रखें, इसका मतलब यह होगा कि ओबीजे के तरीके अब "दृश्यमान" नहीं हैं ... जो मुझे थोड़ा उलझन में डालता है। मुझे इंटरफ़ेस का सिद्धांत मिला है, हालांकि, मैं समझता हूं कि इंटरफेस कुछ विधियां हैं जो 2 कक्षाएं साझा करेंगी, लेकिन मुझे यह समझने की ज़रूरत नहीं है कि: यदि "इंटरफेस" प्रकार है, तो मेरी ओबीजे कक्षा से अन्य विधियां जीतीं – Paul

0

कोड में आपने दिखाया है कि आप कभी भी किसी भी कलाकार को नहीं करते हैं।

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

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

कक्षा परवाह नहीं है कि श्रोताओं क्या करेंगे। यह केवल इस तथ्य पर निर्भर करता है कि यह propertyChange विधि मौजूद होगी, और उस विधि को कॉल करेगी।

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

0
MyInterface mi = new Obj(); 
mi.getInterfaceMethods(); (methods in the MyInterface) 

if(mi instanceof Obj) { 
    mi.getObjMethods(); (methods in the Obj) 
} 
0

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

1
MyInterface myObj = new Obj(); 
MyInterface mySec = new Sec(); 

आप MyObj नामक एक MyInterface का एक उदाहरण घोषित करते हैं। आप इसे नए ओब्जे() के साथ शुरू करते हैं; जो कंपाइलर द्वारा अधिकृत है यदि Obj MyInterface लागू करता है। myObj केवल MyInterface विधियों को स्पष्ट रूप से कॉल कर सकता है। दूसरी पंक्ति के लिए समान है।

public class Test { 

    public static void main(String args[]){ 
      A a = new A(); 
      a.say(); 
      a.a(); 

      B b = new B(); 
      b.say(); 
      b.b(); 

      I ia = new A(); 
      ia.say(); 
      ia.a(); // fail 
    } 

} 

interface i { 
    public void say(); 
} 

class A implements i { 
    public void say(){ 
     System.out.println("class A"); 
    } 
    public void a(){ 
     System.out.println("method a"); 
    } 
} 

class B implements i { 
    public void say(){ 
     System.out.println("class B"); 
    } 
    public void b(){ 
     System.out.println("method b"); 
    } 
} 
+0

धन्यवाद आपके उत्तर के लिए kbdjockey धन्यवाद: ठीक है, लेकिन अगर हमने इंटरफेस के बिना परियोजना शुरू की, तो हम एक इंटरफ़ेस को कार्यान्वित करना चाहते हैं क्योंकि हमें कक्षाओं 'ए' और 'बी' में जोड़े जाने के लिए और अधिक तरीकों की आवश्यकता है: हम 'ए' और' बी 'से पिछली विधियों को खो देंगे क्योंकि हम' ए' और 'बी' घोषित करेंगे क्योंकि मैं ऑब्जेक्ट्स ... – Paul

+0

सिर्फ इसलिए कि 'ए' और' बी 'लागू' i' का मतलब यह नहीं है उन्हें इस तरह तत्काल करना होगा। आप अभी भी 'एक myObj = new A() 'कह सकते हैं, और' ए' के सभी तरीकों तक पहुंच सकते हैं ('I' से उन ओवर्रिडन सहित)। –

0

एक साधारण सादृश्य:

पर विचार एक बावर्ची (इंटरफेस)

यहाँ कोशिश करने के लिए एक नमूना कोड है। और चीनी शेफ (कक्षाएं) और अमेरिकी शेफ (कक्षाएं) हैं। अब, वहाँ

  • शाकाहारी
  • 5 साल
  • का अनुभव है पका सकते हैं एक होटल में कुछ पात्रता मानदंड ऐसे

    रूप
    • गैर शाकाहारी खाना बना सकते हैं के आधार पर एक महाराज की भर्ती के लिए बाहर देख रहा है

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

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

      यह केवल यह निर्दिष्ट करने का विषय है कि होटल किस कौशल (कार्यक्षमता) को ढूंढ रहा है।

      आशा है कि आपको विचार मिल जाएगा।