2009-05-18 14 views
7

में "जावा ™ प्रोग्रामिंग भाषा, चौथा संस्करण" केन अर्नोल्ड, जेम्स गोसलिंग, डेविड होम्स तक, इसकी उल्लेख किया है कि:जावा इंटरफ़ेस: इनहेरिट, अधिभावी, और ओवरलोडिंग के तरीके

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

किसी को भी मुझे कुछ उदाहरण कोड है कि उपरोक्त अनुच्छेद के बिंदु को सही ठहराते हैं दे सकते हैं?

मैं कोड लिखने और परीक्षण क्या उल्लेख किया है की कोशिश की लेकिन मैं हो रही है संकलन-टाइम त्रुटि उप इंटरफ़ेस खाल आधार इंटरफेस विधि इसलिए केवल उप इंटरफ़ेस विधि लागू कर सकते हैं।

अग्रिम धन्यवाद। -अरूण

+0

आप कोड दिखा सकते हैं? –

+1

अपना कोड और अपनी कंपाइलर त्रुटियों को पोस्ट करें ... कम से कम हमें कुछ दें (ए) इस मुद्दे को पुन: उत्पन्न करें; और (बी) वहां से जाओ। – corlettk

+0

हर कोई मुझे वास्तव में खेद है - मैं j2sdk1.4.2_08 का उपयोग कर उपर्युक्त पैरा में जो बताया गया था उसका परीक्षण करने की कोशिश कर रहा था - मुझे एहसास नहीं हुआ कि पुस्तक जेडीके 1.5 के लिए लिखी गई है, इसका मतलब है कि यदि आप कोड स्निपेट संकलित करते हैं जेडीके 1.4 का उपयोग करके "डैनियल स्केनेलर" द्वारा आपको "कार्यान्वयन OfAandB.java:17: methodB() कार्यान्वयन में प्राप्त होगा OFAandB इंटरफ़ेसए में methodB() को कार्यान्वित नहीं कर सकता; असंगत वापसी प्रकार का उपयोग करने का प्रयास कर रहा है" संकलन त्रुटि जबकि JDK1.5 के साथ यह बस चलता है ठीक। – akjain

उत्तर

2

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

दूसरा methodB()InterfaceA में Number (या Number ही) के किसी भी उप-प्रकार लौटने के रूप में परिभाषित किया गया है। InterfaceBmethodB() को Integer लौटने के रूप में परिभाषित करता है जो Number का उप प्रकार है। कार्यान्वयन वर्ग वास्तव में Integer के साथ विधि लागू करता है, इस प्रकार InterfaceA और InterfaceB दोनों के अनुबंध का अनुपालन करता है। यहां कोई समस्या नहीं है। methodB() को Double लौटने के रूप में कार्यान्वित किए जाने पर टिप्पणी की गई, हालांकि यह काम नहीं करेगा: हालांकि यह InterfaceA के अनुबंध को पूरा करेगा, यह InterfaceB (जो Integer की मांग करता है) के साथ संघर्ष करेगा।

InterfaceA और InterfaceB भी (अलग) एक methodC() (उदाहरण में बाहर टिप्पणी की) इस विरोधाभासी हो सकता है और एक संकलक त्रुटि पैदा करेगा के लिए अनुबंध को निर्दिष्ट कर रहे थे। जावा में हस्ताक्षर (केवल रिटर्न प्रकार में भिन्न) दोनों को लागू करने की अनुमति नहीं है।

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

public interface InterfaceA { 
    public int methodA(); 
    public Number methodB(); 
    // public int methodC(); // conflicting return type 
} 

public interface InterfaceB { 
    public int methodA(); 
    public Integer methodB(); 
    // public String methodC(); // conflicting return type 
} 

public class ImplementationOfAandB implements InterfaceA, InterfaceB { 
    public int methodA() { 
     return 0; 
    } 
    public Integer methodB() { 
     return null; 
    } 
    // This would NOT work: 
    // public Double methodB() { 
    //  return null; 
    // } 
} 
+0

हर कोई वास्तव में मुझे खेद है - मैं j2sdk1.4.2_08 का उपयोग कर उपर्युक्त पैरा में जो बताया गया था उसका परीक्षण करने की कोशिश कर रहा था - मुझे नहीं पता था कि पुस्तक जेडीके 1.5 के लिए लिखी गई है, इसका मतलब है कि यदि आप जेडीके 1.4 का उपयोग करके "डैनियल स्केनेलर" द्वारा कोड स्निपेट संकलित करते हैं तो आपको कार्यान्वयन में एक कार्यान्वयन ओफएंडबी.जावा:17: methodB() प्राप्त होगा OFAandB इंटरफेसए में methodB() को कार्यान्वित नहीं कर सकता है; असंगत रिटर्न प्रकार का उपयोग करने का प्रयास "संकलन त्रुटि जबकि जेडीके 1.5 के साथ यह ठीक है। – akjain

1
interface A 
{ 
    void foo(); 
    //int bar(); <-- conflicts with B.bar() because of different return type 
} 

interface B 
{ 
    void foo(); 
    //double bar(); <-- conflicts with A.bar() because of different return type 
} 

class C implements A, B 
{ 
    void foo() // this implements A.foo() AND B.foo() 
    { 
     ... 
    } 
} 
8
interface A { 
    void method(); 
    Object returnMethod(); 
} 
interface B { 
    void method(); 
    B returnMethod(); 
} 

class Impl implements A,B 
{ 
    void method() { } 
    B returnMethod() { } 
} 

आप देख सकते हैं, Impl.method() औजार A.method() और B.method() दोनों है, जबकि Impl.returnMethod() एक B, जो Object का एक बच्चा है देता है, इस प्रकार भी A.returnMethod() के अनुबंध को पूरा करने। क्या बाद वाले को रिटर्न प्रकार की आवश्यकता होगी जो B.returnMethod() के रिटर्न प्रकार का अभिभावक नहीं है जो एक कॉमेइल त्रुटि होगी, क्योंकि Impl में ऐसा कोई कार्यान्वयन मौजूद नहीं था।

+0

लेकिन आईएमएल को ऑब्जेक्ट रिटर्न मोड() को लागू करना है, है ना? –

+0

क्या वह सी # है? सवाल जावा के बारे में है। –

+0

मुझे नहीं लगता कि यह कौन सी भाषा मायने रखता है;) –

1

इस तुम क्या मतलब है ?:

interface A { 
    Object get(); 
} 
interface B { 
    Number get(); 
} 

abstract class MyClass implements A, B { 
    // Try to override A.get, but cause a compile error. 
    public Object get() { return null; } 
} 

इस तरह MyClass में एक विधि स्वचालित रूप से एक कृत्रिम पुल विधि के रूप में javac द्वारा उत्पन्न होता है है। आपको सभी कार्यान्वित/ओवरराइड विधियों (इस मामले में Number/Integer/Double/आदि) के साथ संगत प्रकार को वापस करने वाली एक विधि को कार्यान्वित करना होगा।

1
/** 
* This is what you have 
*/ 
interface IXR { 
     //bla-bla-bla 
} 

class CXR implements IXR { 
     //concrete implementation of bla-bla-bla 
} 

interface IX { 
     public IXR f(); 
} 

interface IYR { 
     //some other bla-bla-bla 
} 

class CYR implements IYR { 
     //concrete implementation of the some other bla-bla-bla 
} 

interface IY { 
     public IYR f(); 
} 






/** 
* This is what you need to add 
*/ 
interface IZR extends IXR, IYR { 
     //EMPTY INTERFACE 
} 

class CZXR extends CXR implements IZR { 
     //EMPTY CLASS 
} 

class CZYR extends CYR implements IZR { 
     //EMPTY CLASS 
} 

class CZ implements IX, IY 
{ 
     public static boolean someCondition = true; 

     public IXR implementationOf_X_f() 
     { 
       System.out.println("CXR"); 
       return new CZXR(); 
     } 

     public IYR implementationOf_Y_f() 
     { 
       System.out.println("CYR"); 
       return new CZYR(); 
     } 

     public IZR f() { 
       if (someCondition) { 
         return (IZR) implementationOf_X_f(); 
       } else { 
         return (IZR) implementationOf_Y_f(); 
       } 
     } 

} 






/** 
* This is the usage of the required class 
*/ 
class program 
{ 
     public static void main(String[] x) { 
       CZ o = new CZ(); 
       IZR r = o.f(); 
       if (CZ.someCondition) { 
         CXR xr = (CXR) r; 
         //bla-bla-bla 
       } else { 
         CYR yr = (CYR) r; 
         //bla-bla-bla 
       } 
     } 
} /** 
* This is what you have 
*/ 
interface IXR { 
     //bla-bla-bla 
} 

class CXR implements IXR { 
     //concrete implementation of bla-bla-bla 
} 

interface IX { 
     public IXR f(); 
} 

interface IYR { 
     //some other bla-bla-bla 
} 

class CYR implements IYR { 
     //concrete implementation of the some other bla-bla-bla 
} 

interface IY { 
     public IYR f(); 
} 






/** 
* This is what you need to add 
*/ 
interface IZR extends IXR, IYR { 
     //EMPTY INTERFACE 
} 

class CZXR extends CXR implements IZR { 
     //EMPTY CLASS 
} 

class CZYR extends CYR implements IZR { 
     //EMPTY CLASS 
} 

class CZ implements IX, IY 
{ 
     public static boolean someCondition = true; 

     public IXR implementationOf_X_f() 
     { 
       System.out.println("CXR"); 
       return new CZXR(); 
     } 

     public IYR implementationOf_Y_f() 
     { 
       System.out.println("CYR"); 
       return new CZYR(); 
     } 

     public IZR f() { 
       if (someCondition) { 
         return (IZR) implementationOf_X_f(); 
       } else { 
         return (IZR) implementationOf_Y_f(); 
       } 
     } 

} 






/** 
* This is the usage of the required class 
*/ 
class program 
{ 
     public static void main(String[] x) { 
       CZ o = new CZ(); 
       IZR r = o.f(); 
       if (CZ.someCondition) { 
         CXR xr = (CXR) r; 
         //bla-bla-bla 
       } else { 
         CYR yr = (CYR) r; 
         //bla-bla-bla 
       } 
     } 
} 
+0

कंडेन्स्ड उत्तर पढ़ने के लिए आसान हैं – davids

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