如果知道要公开的一组API,例如说您想访问length方法和迭代器方法,则可以定义一个接口:
public interface TheInterfaceIWant { int length(); void quack();}
- 如果您希望能够使用此接口来访问未实现此接口的实例上的相应方法,则可以使用代理类:http
- //download.oracle.com/javase/1.4.2/docs/api/java
/lang/reflect/Proxy.html
所以你创建一个代理
final Object aDuck = ...;TheInterfaceIWant aDuckWrapper = (TheInterfaceIWant) Proxy.newProxyInstance( TheInterfaceIWant.class.getClassLoader(), new Class[] { TheInterfaceIWant.class }, new InvocationHandler() { public Object invoke( Object proxy, Method method, Object[] args) throws Throwable { return aDuck.getClass().getMethod( method.getName(), method.getParameterTypes()).invoke(aDuck, args); } });
然后,您可以像使用动态类型语言的鸭子一样使用包装器。
if (aDuckWrapper.length() > 0) { aDuckWrapper.quack();}
这是一个全长可运行示例,该示例使用包装程序将“ Quack”打印四次:
import java.lang.reflect.*;public class Duck { // The interface we use to access the duck typed object. public interface TheInterfaceIWant { int length(); void quack(); } // The underlying instance that does not implement TheInterfaceIWant! static final class Foo { public int length() { return 4; } public void quack() { System.out.println("Quack"); } } public static void main(String[] args) throws Exception { // Create an instance but cast away all useful type info. final Object aDuck = new Foo(); TheInterfaceIWant aDuckWrapper = (TheInterfaceIWant) Proxy.newProxyInstance( TheInterfaceIWant.class.getClassLoader(), new Class[] { TheInterfaceIWant.class }, new InvocationHandler() { public Object invoke( Object proxy, Method method, Object[] args) throws Throwable { return aDuck.getClass().getMethod( method.getName(), method.getParameterTypes()).invoke(aDuck, args); } }); for (int n = aDuckWrapper.length(); --n >= 0;) { // Calling aDuck.quack() here would be invalid since its an Object. aDuckWrapper.quack(); } }}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)