当前位置: 首页 > 知识库问答 >
问题:

在接口中添加默认和静态方法的原因

方永贞
2023-03-14

Java8在接口上引入了默认和静态方法。因此,现在您可以在接口中有具体的实现,不管是使用默认方法还是静态方法。

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

    null

共有1个答案

汪明德
2023-03-14

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

这只适用于默认方法(而不是静态方法),并且省略了一些上下文。来自Goetz,Lambda的状态:

默认方法的目的...是使接口能够在初始发布后以兼容的方式演化。

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

为了支持现有的体系结构问题,为什么要扭曲原本以为完全抽象的接口概念呢?

Java接口的主要目的是指定一个契约,任何类都可以在不改变其在类层次结构中的位置的情况下实现该契约。的确,在Java8之前,接口是纯粹抽象的。但是,这并不是接口的一个基本属性。即使包含默认方法,接口的核心仍然在实现类上指定一个契约。实现类可以重写默认方法,因此类仍然完全控制其实现。(还要注意,默认方法不能是final。)

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

另一个区别是,通过使用受保护的和包专用的访问级别,抽象类可以定义要与子类共享的方法和字段,而不是与调用方共享的html" target="_blank">方法和字段。接口只能具有公共方法。

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

最后,接口中的静态方法不影响类继承,也不是接口契约的一部分。它们仅仅是以更方便的方式组织实用方法的一种方式。例如,静态方法在接口中的常见用法是用于静态工厂方法。如果接口中不允许使用静态方法,则必须将静态工厂方法放在一个伴生类中。在接口中允许静态方法允许这样的方法与接口本身分组(如果这样做是适当的)。

 类似资料:
  • 问题内容: Java 8在接口上引入了默认方法和静态方法。因此,现在无论使用默认方法还是静态方法,您都可以在界面中实现具体的实现。 Java声称添加这两种新方法的原因是“确保与为那些接口的较旧版本编写的代码二进制兼容”。 我的问题: 为什么为了支持现有的体系结构问题而扭曲应该完全抽象的接口原始概念? 使用抽象类和新版本的接口之间的区别除了一个类具有扩展多个接口的能力之外,还有什么区别? 问题答案:

  • 当我注意到现在可以在接口中定义静态和默认方法时,我正在通过接口学习。 请解释两者的区别,如果有一个我们什么时候会使用它的例子,那就好了。界面上有点混乱。

  • 但是随着缺省方法的引入,接口也具有抽象类的所有功能。因此非静态和非最终字段也是必要的。 但当我尝试正常声明一个字段时,默认情况下它变成了静态的和最终的。 在Java8中有没有一种方法可以在接口中声明一个非静态的非final字段。

  • 我试图使用以下代码理解Java接口中的默认方法,但我无法编译它: 编译器生成了以下输出: 我无法理解这些错误。我如何更正代码中的问题?

  • 我有以下场景: 以下是我的问题: 如果中的静态方法是公共的,则编译错误将为: 静态方法m1()与I中的抽象方法冲突。 因此,当访问修饰符是默认值时,它试图隐藏,而当它是公共的时,它是冲突的。为什么会有这样的区别呢?背后的理念是什么?

  • 我想通过创建一个具体实现类的对象来执行接口中默认方法的定义体,该对象也覆盖了该方法。无论我是直接创建具体实现类的对象,还是通过动态绑定/多态,实现类中定义/重写的主体都只是得到执行。请看下面的代码 我想知道如何在控制台内部界面银行打印以下内容--loan()