如何在已经存在但不能在java中修改的类周围创建接口

时间:2018-04-20 18:29:53

标签: java oop interface class-design object-oriented-analysis

假设我的代码中已经有两个类:

class SomeOrder {
  String getOrderId() { return orderId; }
}

class AnotherOrder {
  String getOrderId() { return orderId; }
}

如何在这两个类周围创建一个接口:

interface Order {
    String getOrderId();
}

理想情况下,我会修改代码以便SomOrder implements OrderAnotherOrder implements Order,但这里的问题是它们属于我无法控制或编辑的包(即它们来自外部jar)。

我的算法目前看起来像这样:

void sorter(List<SomeOrder> orders) {
    ... <custom sort logic> ...
    someOrder.getOrderId();
}

void sorter(List<AnotherOrder> orders) {
    ... <custom sort logic> ...
    someOrder.getOrderId();
}

使用单一界面我可以写:

void sorter(List<Order> orders) {
        ... <custom sort logic> ...
        order.getOrderId();
}

3 个答案:

答案 0 :(得分:7)

您可以使用适配器类:

False

class SomeOrderAdapter implements Order { private SomeOrder delegate; @Override public String getOrderId() { return delegate.getOrderId(); } } 类似。

答案 1 :(得分:1)

由于您的界面是一个功能界面,您可以定义映射到这个新Order界面的函数,我为每个不同的类引用getOrderId方法:

private Order wrap(SomeOrder obj) {
    return obj::getOrderId;
}

private Order wrap(AnotherOrder obj) {
    return obj::getOrderId;
}

调用它的一个例子:

private void test() {
    List<Order> orders = Arrays.asList(
        wrap(new SomeOrder()),
        wrap(new AnotherOrder())
    );
    sorter(orders);
}

答案 2 :(得分:0)

创建一个Proxy包围实现所需接口的实例。代理只使用相同的参数调用实例的方法。

public class Proxied<T> implements InvocationHandler {
  private final T wrapped;

  public Proxied(T wrapped) {
    this.wrapped = Objects.requireNonNull(wrapped);
  }

  public T getWrapped() {
    return wrapped;
  }

  public <I> Class<I> proxy(Class<I> interfaceClass) {
    @SuppressWarnings("unchecked")
    Class<I> proxyClass = (Class<I>)  Proxy.getProxyClass(getClass().getClassLoader(), interfaceClass);
    return proxyClass;
  }

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    return method.invoke(wrapped, args);
  }
}