Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 向现有对象添加接口_Java - Fatal编程技术网

Java 向现有对象添加接口

Java 向现有对象添加接口,java,Java,我有一个第三方库,它有一堆接口和构建器来构造实现接口的对象。然后将这些构造的对象传递到容器中。然后,我的应用程序中有一个接口,我想将它的实现添加到从生成器返回的对象中 第三方 interface ThirdParty1 { ... } interface ThirdParty2 { ... } class Builder { ... public ThirdParty1 build() { ... } } class ThirdPartyContainer { void append

我有一个第三方库,它有一堆接口和构建器来构造实现接口的对象。然后将这些构造的对象传递到容器中。然后,我的应用程序中有一个接口,我想将它的实现添加到从生成器返回的对象中

第三方

interface ThirdParty1 { ... }
interface ThirdParty2 { ... }
class Builder {
  ...
  public ThirdParty1 build() { ... }
}
class ThirdPartyContainer {
  void append(ThirdParty1 toAdd) { ... }
  ThirdParty1 take() { ... }
}
我的申请

interface MyInterface { ... }
class MainBody {
  ThirdPartyContainer queue;

  MainBody() {
    ThirdParty1 foo = new Builder().build();
    // something to add implementation of MyInterface to foo 
    queue.append(foo);
  }

  void calledLater() {
    ThirdParty1 bar = queue.take();
    if (bar instanceof MyInterface) {
      // do something
    } else if (bar instanceof ThirdParty2) {
      // do something else
    }
  }
}
我知道我可以构建一个包装器类来实现ThirdParty1和MyInterface,并获取ThirdParty的一个实例,该实例将所有调用转发到其中。但是,这意味着如果Builder.build返回的是第三方1和第三方2的实现,那么第三方2的实现将被包装器丢失


我想我所追求的是不可能的,但是对于Java和所有可以实现的魔法,我并不确定。

只需实现您自己的构建器,它构建MyInterface的实例并在队列中传递这些对象

因为我想要的不可能,所以解决方法是制作包装:

class Wrapper implements ThirdParty1, MyInterface
{
  private ThirdParty1 original;
  Wrapper(ThirdParty1 original_) { original=original_; }
  // all implemented functions from ThirdParty call said method on original
}
这确实意味着,当传递回第三方库时,对象只能被视为第三方1实现,因此可能无法进行优化。如果第三方有很多方法,那么编写所有转发代码也有点痛苦

因此,我们必须采取的替代方案和方法是映射,即

class MainBody {
  Map<ThirdParty1, MyInterface> remapper;
  ThirdPartyContainer queue;
  MainBody() {
    ThirdParty1 foo = new Builder().build();
    remapper.push(foo, new MyInterface() { ... });
    queue.append(foo);
  }

  void calledLater() {
    ThirdParty1 bar = queue.take();
    MyInterface ours = remapper.get(bar);
    if (ours != null) {
      // do something
    } else if (bar instanceof ThirdParty2) {
      // do something else
    }
  }
}

此解决方案的问题是,地图需要能够被执行查找的任何对象访问。查找地图也会对性能造成影响。

不太可能,不可能。Java不是一种动态语言,在这种语言中,这样的事情是可能的,甚至是推荐的用法。如果您进一步解释您的用例,可能会有一个比包装器更方便的解决方案。我的解决方案使用一个映射,该映射根据构建器返回的对实现MyInterface的对象的引用进行索引,这很好,但我希望Java可以允许一个更优雅的解决方案,以防止需要公开该映射。谢天谢地,新对象只是实现MyInterface,而不是第三方1或第三方2。如原始问题中所述,可以实现包装器/转发器类,但只能实现MyInterface和ThirdParty1,隐藏第三方2或任何其他接口,其中返回的对象也已实现。显然,MyInterface应该扩展第三方1和第三方2。如果我完全了解返回值在其中实现的所有接口,这将是可行的,但一旦不知道这一点,它就无法成为可行的解决方案。