当前位置: 首页 > 面试题库 >

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

马国源
2023-03-14
问题内容

Java 8在接口上引入了默认方法和静态方法。因此,现在无论使用默认方法还是静态方法,您都可以在界面中实现具体的实现。

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

我的问题:

  • 为什么为了支持现有的体系结构问题而扭曲应该完全抽象的接口原始概念?
  • 使用抽象类和新版本的接口之间的区别除了一个类具有扩展多个接口的能力之外,还有什么区别?

问题答案:

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

这仅适用于默认方法(不适用于静态方法),并且省略了某些上下文。从Lambda州Goetz出发:

默认方法的目的是使接口在最初发布后能够以兼容的方式发展。

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

为什么为了支持现有的体系结构问题而扭曲应该完全抽象的接口原始概念?

Java接口的主要目的是指定任何类都可以实现的协定,而不必更改其在类层次结构中的位置。的确,在Java
8之前,接口是纯抽象的。但是,这不是接口的基本属性。即使包括默认方法,接口的核心仍然会在实现类上指定一个约定。实现类可以覆盖默认方法,因此该类仍完全控制其实现。(还请注意,默认方法不能是final方法。)

使用抽象类和新版本的接口之间的区别除了一个类具有扩展多个接口的能力之外,还有什么区别?

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

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

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

最后,接口中的静态方法不会影响类的继承,也不是接口协定的一部分。它们仅仅是以更方便的方式组织实用程序的一种方式。例如,接口中静态方法的常见用法是静态工厂方法。如果接口中不允许使用静态方法,则必须将静态工厂方法放在伴随类中。允许在接口中使用静态方法时,可以将此类方法与接口本身组合在一起,如果合适的话。



 类似资料:
  • Java8在接口上引入了默认和静态方法。因此,现在您可以在接口中有具体的实现,不管是使用默认方法还是静态方法。 Java声称添加这两种新方法的原因是“确保与为这些接口的旧版本编写的代码的二进制兼容性”。 null

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

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

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

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

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