2012-03-25 52 views
16

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

(मैं ग्रहण का इस्तेमाल किया है कार्यक्रम सीधे चलाने के लिए, और मैं किसी भी संकलक स्पष्ट रूप से कमांड लाइन से संकलन के द्वारा चेतावनी वगैरह की जाँच करने के। कोशिश नहीं की) क्यों वे समस्या के बिना चला सकता हूँ

? जावा इसे क्यों अनुमति देता है, भले ही यह दोनों इंटरफेस के "अनुबंध" को संतुष्ट करता है लेकिन कक्षा को कार्यान्वित करने में अस्पष्टता पैदा करता है?

उदाहरण अपडेट किया गया।

public interface CassettePlayer { 
    void play(); 
} 

public interface DVDPlayer { 
    void play(); 
} 

public class CarPlayer implements CassettePlayer,DVDPlayer{ 

    @Override 
    public void play() { 
     System.out.println("This plays DVD, screw you Cassette !"); 
    } 

    public static void main(String args[]) { 
     CarPlayer cp = new CarPlayer(); 
     cp.play(); 

     CassettePlayer firstInterface = new CarPlayer(); 
     firstInterface.play(); 

     DVDPlayer secondInterface = new CarPlayer(); 
     secondInterface.play(); 
    } 
} 
+2

वे एक समस्या क्यों होना चाहिए साथ संगत नहीं है? यही सवाल है;) –

+1

यदि आप कामना करते हैं तो आप 'SayHello' विधि के साथ एक अमूर्त वर्ग प्राप्त कर सकते हैं और' नमूना 'को अमूर्त वर्ग का विस्तार कर सकते हैं। कोई समस्या नहीं होगी। – emory

+0

धन्यवाद दोस्त, मेरे पास एक ही सवाल था ... – orchidrudra

उत्तर

34

इस परिदृश्य विशेष रूप से Java Language Specification, section 8.1.5 में अनुमति दी:

यह एक कक्षा में एक भी विधि घोषणा एक से अधिक superinterface के तरीकों को लागू करने के लिए अनुमति दी है। उदाहरण के लिए, कोड में:

interface Fish { int getNumberOfScales(); } 
interface Piano { int getNumberOfScales(); } 
class Tuna implements Fish, Piano { 
    // You can tune a piano, but can you tuna fish? 
    int getNumberOfScales() { return 91; } 
} 

विधि getNumberOfScales वर्ग Tuna में एक नाम, हस्ताक्षर है, और वापस जाने के प्रकार है कि विधि इंटरफ़ेस Fish में घोषित मेल खाता है और यह भी विधि इंटरफ़ेस Piano में घोषित मेल खाता है; यह दोनों को लागू करने के लिए माना जाता है।

पाठ तो ध्यान दें कि यदि विधि हस्ताक्षर ऐसे double और int के रूप में विभिन्न वापसी प्रकार, था, वहाँ एक ही कक्षा और एक संकलन समय त्रुटि में दोनों इंटरफेस को लागू करने के कोई रास्ता नहीं उत्पादन किया जाएगा, वे पर चला जाता है ।

1

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

1

क्यों नहीं? कक्षा दोनों इंटरफेस द्वारा परिभाषित अनुबंधों को संतुष्ट कर रही है।

1

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

5

इस मुद्दे के लिए यह समझना आवश्यक है कि इंटरफेस क्या हैं।

एक इंटरफ़ेस एक प्रकार का "अनुबंध" है ताकि कोई जानता है कि उस इंटरफ़ेस के साथ कक्षा में कौन सी विधियां अनिवार्य रूप से कार्यान्वित की गई हैं।

तो यदि आपको "डीवीडीप्लेयर" लागू करने वाली कक्षा की आवश्यकता है (क्योंकि आपको "play()" विधि की आवश्यकता है), तो आपको कारप्लेयर मिल जाएगा। एक वर्ग लागू करने के लिए कैसेटप्लेयर की आवश्यकता के लिए चला जाता है। यह तकनीकी स्पष्टीकरण है।

लेकिन निश्चित रूप से आपके अर्थपूर्ण कोडिंग में आपको यह सुनिश्चित करना चाहिए कि कारप्लेयर की विधि "play()" DVDPlayer और कैसेटप्लेयर दोनों के अर्थशास्त्र को संतुष्ट करती है। मुझे लगता है कि एक व्यावहारिक अनुप्रयोग में यह एक बुरा अभ्यास होगा।

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

1

इस स्थिति में है क्योंकि दोनों इंटरफेस एक ही विधि का हस्ताक्षर है, वहाँ कोई समस्या नहीं है। लेकिन इसके बारे में क्या?

interface Animal { 
    public void eat() throws IOException; 
} 

interface Plants { 
    public void eat() throws NullPointerException; 
} 

संकलक द्वारा कौन सा चयन किया जाता है? कोड के नीचे त्रुटि क्यों प्राप्त होती है?

public class Test implements Animal, Plants { 

    public void eat() throws IOException { 

    } 
} 

संकलक का कहना है: अपवाद IOException Plants.eat() में खंड फेंकता

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