Java 是否计划用默认方法 (java8) 替代摘要 Class?

Does Java have plan that default method (java8) Substitute for Abstract Class?

Java是否有计划default method替代Abstract Class? 我找不到使用默认方法而不是抽象方法的真实案例?

在接口中引入默认方法的原因之一是允许向 JDK 接口添加新方法。

如果没有此功能,一旦 class 已使用特定版本的接口进行编译,则无法向该接口添加新方法。使用接口功能接口中的默认方法可以更改。

默认方法不能替代抽象 classes,因为抽象 classes 可以(而且经常)有字段。接口只能包含行为而不是状态,这在未来不太可能改变,因为 Java 中的状态多重继承被(正确或错误地)视为邪恶。

它们也可以有 final 方法,这是你无法用 default 方法模仿的另一件事。

如果有的话,带有默认方法的接口类似于 traits 而不是抽象的 classes,但匹配并不完美。使用接口作为特征是一件必须非常小心地完成的事情,并且要知道它们带来的局限性。 (例如任何实现 class 的方法都可以重写 default 方法,可能会破坏特性。)

关于此的更多信息

没有这样的计划,你可以通过比较已经记录的意图得出,这与这样的计划的含义不同:

:

The main goal is to allow interface evolution, that is, the addition of new methods. If a new method is added to an interface, existing classes that implement the interface would be missing an implementation, which would be incompatible. To be compatible, an implementation has to come from somewhere, so it is provided by default methods.

The main intent of a Java interface is to specify a contract that any class can implement without having to alter its position in the class hierarchy. It's true that, prior to Java 8, interfaces were purely abstract. However, this is not an essential property of interfaces. Even when default methods are included, an interface at its heart still specifies a contract upon the implementing class. The implementing class can override default methods, so the class is still in complete control of its implementation. (Note also that default methods cannot be final.)

:

The proximate reason for adding default methods to interfaces was to support interface evolution, …

Here are some use cases that are well within the design goals:

  • Interface evolution. Here, we are adding a new method to an existing interface, which has a sensible default implementation in terms of existing methods on that interface. An example would be adding the forEach method to Collection, where the default implementation is written in terms of the iterator() method.

  • "Optional" methods. Here, the designer of an interface is saying "Implementors need not implement this method if they are willing to live with the limitations in functionality that entails". For example, Iterator.remove was given a default which throws UnsupportedOperationException; since the vast majority of implementations of Iterator have this behavior anyway, the default makes this method essentially optional. (If the behavior from AbstractCollection were expressed as defaults on Collection, we might do the same for the mutative methods.)

  • Convenience methods. These are methods that are strictly for convenience, again generally implemented in terms of non-default methods on the class. The logger() method in your first example is a reasonable illustration of this.

  • Combinators. These are compositional methods that instantiate new instances of the interface based on the current instance. For example, the methods Predicate.and() or Comparator.thenComparing() are examples of combinators.

请注意,这些并不针对抽象 classes 的主要领域,例如提供框架实现。除了 technical differences,抽象 classes 在语义上是不同的,因为它们承担关于 如何 实现功能的设计决策,哪些接口,甚至 default方法,不应该。例如。一个众所周知的例子是 List 接口,存在两个根本不同的抽象 classes,AbstractListAbstractSequentialList 以及 subclasses 的选择接口不应排除完全不同的两者之一或实现 List 。因此 List 接口定义了契约,永远不能替代提供特定基础实现的抽象 class。

其他答案和其他材料的链接已经充分涵盖了接口和抽象 classes 之间的技术差异。没有很好地涵盖的是为什么要使用一个而不是另一个。

考虑在 Java 中使用 class 或接口的两种不同方式:作为 caller 或作为 subclass呃。调用者有一个对象引用,可以调用 public 方法并通过该引用访问 public 字段。 subclasser 还可以访问、调用和覆盖 superclass 的 protected 成员。 类 可以有 protected 个成员,但接口不能。

一个常见的问题似乎是,既然我们有了默认方法,为什么还需要抽象 classes?默认方法是接口呈现给调用者的一部分。 class 上的 protected 方法对调用者不可用;它仅适用于子class用户。因此,如果你想与 subclassers 共享实现,则使用 class(或抽象 class)并定义 protected 成员和字段。

protected 机制允许 class 与子 class 用户通信,这与它与呼叫者通信的方式不同。

但是 OP 提出了相反的问题:为什么要使用默认方法而不是抽象 classes?在您实际上可以选择的情况下(即,您的抽象不需要状态,或受保护的方法,或任何抽象 classes 具有接口没有的东西),具有默认方法的接口远比抽象 classes 更少限制。您只能继承一个 class;您可以继承许多接口。因此,具有默认方法的接口可以表现得像无状态特征或混合,允许您从多个接口继承行为。

鉴于接口和抽象 classes 用于不同的目的,因此没有删除或替换任何内容的计划。