design-patterns - Java 默认接口(interface)方法具体用例

标签 design-patterns interface java-8 java-9 default-method

Java 9 即将到来,更多特性将被添加到 Java 接口(interface)中,例如私有(private)方法。 default接口(interface)中的方法是在 Java 8 中添加的,本质上是 support the use of lambdas inside collections不会破坏与该语言先前版本的追溯兼容性。

在 Scala 中,trait 中的方法s 非常好用。然而,Scala 有不同的处理方法 trait s 比 Java 和 default方法。考虑多重继承解决方案或使用trait s 作为 mixins。

除了上面的使用,这些都是使用default的真实场景。方法值得吗?在这几年中是否出现了一些使用它们的模式?使用这种方法可以解决哪些问题?

最佳答案

Brian Goetz 和我在我们的 JavaOne 2015 演讲中介绍了其中的一些内容,即使用 Java 8 Lambda 和 Streams 进行 API 设计。尽管有标题,但最后还是有一些关于默认方法的 Material 。

幻灯片:https://stuartmarks.files.wordpress.com/2015/10/con6851-api-design-v2.pdf

视频:https://youtu.be/o10ETyiNIsM?t=24m

我将在这里总结我们所说的关于默认方法的内容。

接口(interface)演进

默认方法的主要用例是接口(interface)演化。主要是,这是在不破坏向后兼容性的情况下向接口(interface)添加方法的能力。如问题中所述,这主要用于添加允许将集合转换为流的方法以及将基于 lambda 的 API 添加到集合。

不过,还有其他几个用例。

可选方法

有时接口(interface)方法在逻辑上是“可选的”。例如,考虑不可变集合上的 mutator 方法。当然,实现是必需的,但通常在这种情况下它会做的是抛出异常。这可以通过默认方法轻松完成。如果他们不想提供异常抛出方法,实现可以继承它,或者如果他们想提供一个实现,他们可以覆盖它。示例: Iterator.remove .

便捷方法

有时为了调用者的方便提供了一个方法,并且有一个明显的优化的实现。此实现可以由默认方法提供。实现覆盖默认值是合法的,但通常没有理由,因此实现通常会继承它。示例: Comparator.reversed , Spliterator.getExactSizeIfKnown , Spliterator.hasCharacteristics .请注意 Spliterator 是在 Java 8 中引入的,包括默认方法,所以这显然不是接口(interface)演变的情况。

简单的实现,旨在被覆盖

默认方法可以提供适用于所有实现的简单通用实现,但这可能不是最理想的。这有助于在初始启动期间实现,因为它们可以继承默认值并确保正确操作。但是,从长远来看,实现可能希望覆盖默认值并提供改进的定制实现。

示例: List.sort .默认实现将列表元素复制到临时数组,对数组进行排序,然后将元素复制回列表。这是一个正确的实现,有时无法改进(例如,对于 LinkedList )。但是, ArrayList 覆盖 sort 并就地对其内部数组进行排序。这避免了复制开销。

现在,显然 sort retrofit 到 ListArrayList在 Java 8 中,所以进化并没有以这种方式发生。但是你可以很容易地想象出一个新的List执行。您最初可能会继承 sort默认实现,而您正在正确实现基础知识。稍后,您可能会考虑实现一个定制的排序算法,该算法已针对您的新实现的内部数据组织进行了调整。

关于design-patterns - Java 默认接口(interface)方法具体用例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43661433/

相关文章:

java - PMD 5.4.2 中可能存在上帝类别违规

scala - 如何对 2 个以上的情况确定隐式优先级

c# - 为什么实现带有类型约束的泛型接口(interface)的泛型类需要重复这些约束?

java - 为什么在java中接口(interface)中的静态最终变量可以被本地变量覆盖?

c++ - Do-While(false) block 与返回的效率

c# - MVVM 违规

c# - 向接口(interface)属性添加约束

Java 8,在Lambda中转换hashmap程序

java - 第一次尝试 lambda

java - 使用 Gradle/Java8 构建时存储某些类的方法参数名称