有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

何时使用:Java8+接口默认方法与抽象方法

Java8允许在名为Default Methods的接口中默认实现方法

我不知道什么时候我会使用那种interface default method,而不是abstract class(带abstract method(s)

那么什么时候应该使用默认方法的接口,什么时候应该使用抽象类(带有抽象方法)?抽象类在该场景中仍然有用吗


共 (6) 个答案

  1. # 1 楼答案

    这两个是完全不同的:

    默认方法是向现有类添加外部功能,而不更改其状态

    抽象类是一种普通的继承类型,它们是普通类,用于扩展

  2. # 2 楼答案

    有一些技术上的差异。与Java 8接口相比,抽象类仍然可以做得更多:

    1. 抽象类可以有一个构造函数
    2. 抽象类更结构化,可以保存状态

    从概念上讲,defender方法的主要目的是在Java8中引入新特性(如lambda函数)后实现向后兼容性

  3. # 3 楼答案

    如第条所述

    Java 8中抽象类与接口的对比

    After introducing Default Method, it seems that interfaces and abstract classes are same. However, they are still different concept in Java 8.

    Abstract class can define constructor. They are more structured and can have a state associated with them. While in contrast, default method can be implemented only in the terms of invoking other interface methods, with no reference to a particular implementation's state. Hence, both use for different purposes and choosing between two really depends on the scenario context.

  4. # 4 楼答案

    这将在本article中描述。想想集合的forEach

    List<?> list = …
    list.forEach(…);
    

    The forEach isn’t declared by java.util.List nor the java.util.Collection interface yet. One obvious solution would be to just add the new method to the existing interface and provide the implementation where required in the JDK. However, once published, it is impossible to add methods to an interface without breaking the existing implementation.

    The benefit that default methods bring is that now it’s possible to add a new default method to the interface and it doesn’t break the implementations.

  5. # 5 楼答案

    每当我们在抽象类和接口之间进行选择时,我们都应该(几乎)选择默认(也称为defender或virtual extensions)方法

    1. 默认方法已经结束了接口的经典模式,以及实现该接口中大部分或所有方法的伴随类。例如Collection and AbstractCollection。现在我们应该在接口本身中实现这些方法,以提供默认功能。实现接口的类可以选择重写方法或继承默认实现

    2. 默认方法的另一个重要用途是interface evolution。假设我有一个班级舞会:

      public class Ball implements Collection { ... }

    现在在Java8中引入了一个新的特性流。我们可以使用添加到接口中的stream方法获得流。如果stream不是默认方法,那么Collection接口的所有实现都会中断,因为它们不会实现这个新方法。向接口添加非默认方法不是source-compatible

    但是假设我们不重新编译这个类,而是使用一个包含这个类的旧jar文件Ball。如果没有这个缺少的方法,类将很好地加载,可以创建实例,看起来一切都很好但是如果程序在Ball的实例上调用stream方法,我们将得到AbstractMethodError。因此,将方法设置为默认值解决了这两个问题

    Java9在接口中甚至有私有方法,可用于封装提供默认实现的接口方法中使用的公共代码逻辑

  6. # 6 楼答案

    抽象类比默认方法实现(比如私有状态)要多得多,但是从Java8开始,只要您可以选择其中一种,就应该在接口中使用defender(aka.default)方法

    默认方法的约束是,它只能通过调用其他接口方法来实现,而不参考特定实现的状态。因此,主要用例是更高级别和方便的方法

    这个新特性的好处是,在您被迫使用一个抽象类来实现方便的方法,从而将实现者限制为单一继承之前,现在您可以拥有一个真正干净的设计,只需接口和程序员所需的最小实现工作量

    default方法引入Java8的最初动机是希望使用面向lambda的方法扩展集合框架接口,而不破坏任何现有的实现。虽然这与公共图书馆的作者更相关,但您可能会发现同样的功能在您的项目中也很有用。您有一个集中的地方可以添加新的便利性,而不必依赖于类型层次结构其余部分的外观