आप ऐसा करने के लिए Proxy
उदाहरण का उपयोग करने में सक्षम हो सकते हैं।
InvocationHandler
है कि आप को देखने के लिए जो इंटरफ़ेस विधि कॉल और अपने ऑब्जेक्ट के अंदर उचित विधि को सौंपने के लिए किया जा रहा है की जाँच करेगा लिखने Proxy
पर जानकारी के लिए this question देखें (विशेष रूप से, दूसरा जवाब का हिस्सा है।)।
public class MyClass {
// Note that we aren't implementing the interfaces anymore
public int doSomethingForA() {
return 0;
}
public int doSomethingForB() {
throw new IllegalArgumentException();
}
}
फिर अपने InvocationHandler:
public class MyClassInvocationHandler implements InvocationHandler {
private MyClass target;
public MyClassInvocationHandler(MyClass target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
if (method.getDeclaringClass().equals(InterfaceA.class))
return MyClass.getMethod("doSomethingForA").invoke(target, args);
else if (method.getDeclaringClass().equals(InterfaceB.class))
return MyClass.getMethod("doSomethingForB").invoke(target, args);
else
throw new UnsupportedOperationException("Unsupported interface: " + method.getDeclaringClass());
} catch (NoSuchMethodException ex) {
throw new UnsupportedOperationException("Method not found", ex);
} catch (IllegalAccessException ex) {
throw new UnsupportedOperationException("Method was not public", ex);
} catch (InvocationTargetException ex) {
// May throw a NullPointerException if there is no target exception
throw ex.getTargetException();
}
}
}
तब प्रॉक्सी बनाने के लिए, आप दोनों इंटरफेस में पारित करेंगे:
Proxy.newProxyInstance(null, new Class<?>[] { InterfaceA.class, InterfaceB.class }, new MyClassInvocationHandler(mc));
मैं लगता यहाँ अपने कार्यान्वयन दिखता है की तरह है यह काम करेगा। जब आप इसे एक इंटरफेस या अन्य का उपयोग करते हुए कहते हैं:
MyClass mc = new MyClass();
Object proxy = Proxy.newProxyInstance(null, new Class<?>[] { InterfaceA.class, InterfaceB.class }, new MyClassInvocationHandler(mc));
InterfaceA a = (InterfaceA) proxy;
a.doSomething();
InterfaceB b = (InterfaceB) proxy;
b.doSomething();
तो यह चाहिए विभिन्न घोषित वर्गों के साथ Method
वस्तुओं में पास। मुझे यकीन नहीं है कि यह इस तरह काम करता है, इसलिए इसका परीक्षण करने की आवश्यकता होगी।
आप कोई दूसरा रास्ता हस्ताक्षर से एक को बदलने के लिए की तुलना में है ओवरलोड। आपके पास एक ही कक्षा में समान हस्ताक्षर के साथ दो विधियां नहीं हो सकती हैं। –
.NET में आप इंटरफ़ेस सदस्यों को स्पष्ट रूप से कार्यान्वित कर सकते हैं, ताकि जब तक कि विशेष इंटरफ़ेस प्रकार पर उदाहरण डाला न जाए, तब तक वे निजी दिखाई देते हैं। तो आप स्पष्ट रूप से दोनों कार्यान्वयन को लागू कर सकते हैं। क्या जावा का एक समान निर्माण है? – jrummell
@jrummell नहीं, इंटरफेस से विधियों * को सार्वजनिक घोषित किया जाना चाहिए। साथ ही, सटीक उसी हस्ताक्षर के साथ दो विधियां (वापसी प्रकार, नाम, और पैरामीटर/पैरामीटर ऑर्डर सभी समान हैं), भले ही एक्सेसर्स अलग हैं, और यहां तक कि यदि कोई स्थिर रूप से घोषित किया गया है और अन्य गैर-स्थैतिक * आपको कंपाइलर त्रुटियां – Brian