是否可以将默认实现添加到表示侦听器的接口的方法中?

2022-09-03 02:29:20

在我的项目中使用了一个特定的库。这个库有一个接口,里面有大约15个方法。

此接口的目的是可以订阅库中生成的某些事件。应用程序中的侦听器类可以实现此接口,并在库中将自身注册为侦听器以接收事件。

此接口中的所有方法实际上都是事件。可能有侦听器只需要从接口中的许多事件中接收一个或两个事件。即使侦听器只对少数事件感兴趣,侦听器在扩展接口时也必须实现所有方法。

因此,我要求此库的开发人员向接口中的方法添加空的默认实现。

但是库开发人员拒绝添加默认实现,声称这将违反java最佳实践,并且在接口方法中使用默认实现违背了接口的目的。

但是,正如我所理解的,此接口中的方法未指定此接口的实现者应能够执行的某些操作。此接口中的方法定义实现者可能感兴趣的事件。因此,我看不出不添加默认实现的明确理由。

那么,向此接口添加默认实现是否会破坏 Java 最佳实践?


答案 1

但是库开发人员拒绝添加默认实现,声称这将违反java最佳实践,并且在接口方法中使用默认实现违背了接口的目的。

在引入默认接口方法之前,此参数一直有效。现在,您的同事不得不争辩说,Java 8接口的 JLS 和 JDK 现在包含与接口目的相悖的类。这仍然是一个可行的极端立场,但毫无结果。

您可以通过从库接口派生自己的接口并为所有继承的方法提供默认的空实现来避免讨论。

public interface MyInterface extends LibraryInterface {
    @Override default public void event1() {
    }

    ...
}

或者你们俩都可以查看以下设计,这对我来说似乎很可疑,并导致您讨论接口中的默认方法:

即使侦听器只对少数事件感兴趣,侦听器在扩展接口时也必须实现所有方法。

解决方案可能是简单地将大接口拆分为许多较小的接口。


答案 2

库开发人员在这一点上是错误的(我甚至敢省略恕我直言)。

Java中引入许多帮助器(包括抽象和具体)类的原因之一正是缺乏默认接口方法等功能(例如,Swing中的适配器类,它们非常类似于您所询问的问题)。

如果不被误用,多重继承在某些情况下是可取的,而且众所周知,通过在Java中扩展“helper”类,我们正在失去从其他任何东西继承的能力。

实际上,这在官方Java教程的“抽象类与接口的比较”一节中提到过:

如果以下任何语句适用于您的情况,请考虑使用接口:

  • 您希望不相关的类能够实现您的接口。例如,可比较和可克隆的接口由许多不相关的类实现。
  • 您希望指定特定数据类型的行为,但不关心谁实现了其行为。
  • 您希望利用类型的多重继承。

我认为第二点和第三点是与您的用例的完美匹配。