为什么在Java 8中向接口添加默认方法是一个不错的设计选择,还有哪些替代方案

2022-09-02 04:40:15

我只是在学习Java,所以我很难获得可能的替代方案,以及这种设计决策的影响。

Java 8 将默认方法功能添加到接口中,这允许接口具有实现。这允许使用新方法扩展现有接口,而不会破坏客户端,随着时间的推移以向后兼容的方式发展接口。但是,给定默认实现,此类扩展受到一定限制,并且很可能使用接口或库方法的现有接口方法实现。所以我的问题是

  • 为什么引入此语言功能?
  • 它支持哪些关键新功能?(例如拆分器)
  • 还有哪些其他替代方案来支持这些语言功能?例如,为什么不创建一个扩展迭代的新接口 SplitIterable?
  • 实现这些替代方案(接口的污染)会产生什么影响?
  • 当可以在接口的第一版中为方法提供默认实现时,是否可以将其实现为其他方法的组合?

答案 1

为什么引入此语言功能?

添加它主要是为了让您在不破坏每个人的代码的情况下将方法添加到已在使用的现有接口中,而且还可以在实现相同接口的类之间“水平”共享方法实现(而不是通过继承进行“垂直”共享)。

它支持哪些关键新功能?(例如Splititerators)

java.util.Collection<T>.stream()

还有哪些其他替代方案来支持这些语言功能?例如,为什么不创建一个扩展的新接口?SplitIterableIterable

您可以选择全新的接口,并继续使用关联的静态帮助程序类(例如 接口及其帮助程序类)。这并不可怕 - 事实上,有人可能会争辩说,默认方法纯粹是静态方法之上的语法糖*。但是,默认方法通常提供更好的可读性。Collection<T>Collections

实现这些替代方案(接口的激增)会产生什么影响?

你最终会得到一个不太一致的库,以及一种可读性较差的语言,但这不会是世界末日。正如Joachim Sauer所指出的那样,一个更大的问题是,接口实现将无法覆盖静态帮助器类中的实现。这将剥夺灵活性。

当可以在接口的第一版中为方法提供默认实现时,是否可以将其实现为其他方法的组合?

仅当需要“水平”共享实现时,才应执行此操作。如果某个方法提供了实现的基本行为,则不要为其提供默认值。

*这将是过度简化,因为默认方法仍然是虚拟的。感谢Brian Goetz的评论。


答案 2