Proxy
これを行うためにインスタンスを使用できる場合があります。詳細については、この質問を参照してくださいProxy
(特に、回答の2番目の部分)。
作成した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
これがどのように機能するかはわかりませんが、これはテストする必要があります。