java - 在接口(interface)中添加默认和静态方法的原因

标签 java oop interface java-8

Java 8 在接口(interface)上引入了默认方法和静态方法。所以现在无论是使用默认方法还是静态方法,您都可以在接口(interface)中拥有具体的实现。

Java 声称添加这两种新方法的原因是“确保与为这些接口(interface)的旧版本编写的代码的二进制兼容性”。

我的问题:

  • 为什么要歪曲界面本来应该是的概念 完全抽象以支持现有的架构问题?
  • 除了类扩展多个接口(interface)的能力之外,使用抽象类和接口(interface)的新版本有什么区别?

最佳答案

The reason java claimed to add these 2 new kind of methods is "ensure binary compatibility with code written for older versions of those interfaces".

这仅适用于默认方法(不是静态方法)并省略了一些上下文。来自 Goetz, State of the Lambda :

The purpose of default methods ... is to enable interfaces to be evolved in a compatible manner after their initial publication.

主要目标是允许接口(interface)进化,即添加新方法。如果将新方法添加到接口(interface),则实现该接口(interface)的现有类将缺少实现,这将是不兼容的。为了兼容,一个实现必须来自某个地方,因此它由默认方法提供。

Why to distort the interface original concept that suppose to be fully abstract in order to support existing architectural problems?

Java 接口(interface)的主要目的是 specify a contract任何类都可以实现而不必改变其在类层次结构中的位置。的确,在 Java 8 之前,接口(interface)是纯粹抽象的。但是,这不是接口(interface)的基本属性。即使包含默认方法,其核心的接口(interface)仍会指定实现类的契约。实现类可以覆盖默认方法,因此该类仍然完全控制其实现。 (还要注意 default methods cannot be final 。)

What is the difference between using an abstract class and the new version of the interface other than the ability of a class to extend multiple interfaces?

类扩展多个接口(interface)的能力与接口(interface)和抽象类的另一个区别密切相关,即接口(interface)不能包含状态。这是允许多重继承的主要困难:如果一个父类(super class)在一个类的祖先中出现多次,那么该父类(super class)的状态会只出现一次还是多次? (这就是所谓的“菱形继承(钻石问题)”。)

另一个区别是抽象类可以通过使用 protected 和包私有(private)的访问级别来定义要与子类共享的方法和字段,但不能与调用者共享。接口(interface)只能有公共(public)方法。

(在 Java 9 中,添加了对私有(private)方法的支持。这对于接口(interface)的默认或静态方法之间的实现共享很有用。)

最后,接口(interface)中的静态方法不影响类继承,也不是接口(interface)契约的一部分。它们只是一种以更方便的方式组织实用方法的方式。例如,接口(interface)中静态方法的常见用途是用于静态工厂方法。如果接口(interface)中不允许使用静态方法,则必须将静态工厂方法放在伴随类中。在接口(interface)中允许静态方法可以让这些方法在适当的时候与接口(interface)本身组合在一起。

关于java - 在接口(interface)中添加默认和静态方法的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29997052/

相关文章:

JavaScript:如何绑定(bind)一个方法?

c# - 尽管有一个方法,但没有找到合适的方法来覆盖 c#?

java - 使用泛型会导致未经检查的转换警告

java - 如何使用正则表达式分割字符串

java - 如何在 NetBeans 中将 Java 代码从 jsp 页面中分离出来?

cocoa - 应该由 View 还是 Controller 负责拖动处理?

linux - 瓦拉文件导入

java - moxy jaxb : mapping member attribute

JAVA - 在接口(interface)中定义一个方法

function - Golang 文档中 "a"之前的 "..."和 "interface{}"是什么意思?