扩展在java中实现接口的三个类

6ovsh4lw  于 2021-07-03  发布在  Java
关注(0)|答案(2)|浏览(404)

我使用一个带有接口ifc的库,它由三个类a、b和c实现。
我想自己实现方法m,它在ifc中定义,在a、b和c中实现,应该覆盖a、b和c中相应的方法。
有可能吗?
在java中,实现而不是扩展接口,只能扩展一个类。这使我得出结论,我想做的是不可能的。
相反,我需要创建:

class MyA extends A {

    myM () {
        // Do my stuff
        super.M();
    }

然后是b和c的两个相同的类,每个类都有一个相同的mym方法,但这感觉非常笨拙和丑陋。还有别的办法吗?

72qzrwbm

72qzrwbm1#

使用此库的简化实现,使用 method() 而不是 M() :

interface IFC {
  void method();
}

class A implements IFC {
  public void method() {
    System.out.println("method in A");
  };
}

正如阿库兹明尼赫在评论中提到的那样
您将编写一个类,其中包含m和一个ifc字段。在m中,你会做你的工作,然后给m打电话给ifc,ifc可以是a,b或c。所以您应该将a、b和c的所有示例 Package 在这样一个类中,这样可以避免扩展a、b和c。
这样做的好处是,您只需在通过 Package 初始化类时对其进行说明: IFC wrapIFC = new IFCWrapper(new A()); . 完成后,就不需要处理变量了 wrapIFC 与初始化任何变量的方式不同 new A() :

class IFCWrapper implements IFC {
  IFC ifc;

  IFCWrapper(IFC ifc) {
    this.ifc = ifc;
  }

  public void method() {
    always();
    ifc.method();
  }

  void always() {
    System.out.println("wrapper method");
  }
}

您还可以创建一个单独的独立(抽象?)类或接口,您可以调用它而不是调用它 method() 传递你的示例。缺点是每次你想打电话的时候都要记得打这个 method() 以你为例。我使用一个 Runnable :

class IFCExt {
  static Runnable defaultRun = () -> System.out.println("default extra");
  static void method(Runnable toRun, IFC ifc) {
    toRun.run();
    ifc.method(); 
  }
}

两种变体的运行示例:

public class Test {
  public static void main(String[] args) { 
    IFC wrapIFC = new IFCWrapper(new A());
    wrapIFC.method();

    System.out.println();

    IFC myIFC = new A();
    IFCExt.method(IFCExt.defaultRun, myIFC);
    IFCExt.method(() -> System.out.println("anything extra"), myIFC); // anything you'd want
  }
}

印刷品:

wrapper method
method in A

default extra
method in A
anything extra
method in A
um6iljoc

um6iljoc2#

我以前遇到过这样的情况。如果只在库的外部使用a、b和c,那么proxy/adapter就很好了,但是在库的内部使用时,可能需要替换从a、b和c调用的m()。
我遇到的例子是一个遗留库,它使用了一个非线程安全的集合,您只想将其切换出去。我将假设情况与我的情况类似,您只能访问一个jar,但没有源代码,并且您还希望更改m()的内部用法。在这种情况下,正如许多人指出的那样,通过常规java代码实现这一点是不可能的。
但是,如果代码在您的计算机上,有两种技术超出了正常java开发的界限,您可以使用它们。它们的使用可能会对构建复杂性和正在编写的代码的维护产生巨大的影响。
如果您真的想替换m()的每个示例而不创建自己的类,一个可能的解决方案是在运行时交换方法。
有些图书馆声称能够做到这一点。这个问题详细讨论了这个技术,并强调了一个库,hotswapagent可以做到这一点。
另一个解决方案是反编译库的jar,更改有问题的方法并重新编译它。取决于库对其他依赖项的使用和构建的复杂性,这可能是非常重要的。你也处于这样一种情况,你必须保持新的改变jar。如果库更新,则必须重复此过程。

相关问题