您可能可以使用Proxy
实例执行此操作。对Proxy
信息请参见this question(特别是第二部分答案。)
,你会写检查,看看哪一个接口被用来调用该方法,并委托给你的对象内部的相应方法的InvocationHandler
。这里是你实现的样子:
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中,您可以显式地实现接口成员,以便它们显示为私有的,除非实例被转换为特定的接口类型。所以你可以明确地实现两个实现。 Java是否有类似的构造? – jrummell
@jrummell不,接口*的方法必须声明为public。另外,即使访问器不同,*和即使一个是静态声明的,另一个是非静态的*,但具有完全相同签名的两个方法(返回类型,名称和参数/参数顺序都是相同的)会给你编译器错误 – Brian