java - 扩展其他接口(interface)的默认方法和接口(interface)

标签 java java-8 default-method

假设有两个接口(interface)Interface1Interface2,其中Interface2扩展Interface1

interface Interface1 {

    default void method() {
        System.out.println("1");
    }

    // Other methods
}

interface Interface2 extends Interface1 {

    @Override
    default void method() {
        System.out.println("2");
    }

    // Other methods
}

假设我想创建一个实现 Interface2 的类,但我希望 method() 成为 Interface1 中的版本。如果我写

class MyClass implements Interface1, Interface2 {

    public void method() {
        Interface1.super.method();
    }
}

我得到编译错误:

bad type qualifier in default super call: redundant interface Interface1 is extended by Interface2

可以通过创建第三个接口(interface)来解决这个问题:

interface Interface3 extends Interface1 {

    default void method() {
        Interface1.super.method();
    }
}

然后:

class MyClass implements Interface1, Interface2, Interface3 {

    public void method() {
        Interface3.super.method();
    }
}

这编译得很好,如果我实例化一个新的 MyClass 并调用 method(),输出是 1 正如预期的那样。

所以我的问题是,鉴于很容易绕过限制,您只能为链中最具体的接口(interface)编写 InterfaceName.super.method(),那么什么是限制的原因?首先禁止您编写 Interface1.super.method() 可以防止哪些问题?

最佳答案

JLS 在 15.12.3. 中完全解决了这个问题“编译时第 3 步:选择的方法是否合适?”.

If the form is TypeName . super . [TypeArguments] Identifier, then:

  • […]
  • If TypeName denotes an interface, let T be the type declaration immediately enclosing the method invocation. A compile-time error occurs if there exists a method, distinct from the compile-time declaration, that overrides (§9.4.1) the compile-time declaration from a direct superclass or direct superinterface of T.

JLS 继续解释为什么制定该规则:

In the case that a superinterface overrides a method declared in a grandparent interface, this rule prevents the child interface from "skipping" the override by simply adding the grandparent to its list of direct superinterfaces. The appropriate way to access functionality of a grandparent is through the direct superinterface, and only if that interface chooses to expose the desired behavior.

所以它或多或少是专门用来阻止你做你想做的事情的。

但 JLS 似乎也承认您的解决方法:

(Alternately, the developer is free to define his own additional superinterface that exposes the desired behavior with a super method invocation.)

关于java - 扩展其他接口(interface)的默认方法和接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29525975/

相关文章:

java - 从java中的CompletionStage获取值

java - 界面中的默认方法在命令提示符下运行,但在 eclipse 中不运行

允许公共(public)默认方法的 java8 接口(interface)

java - 在Java的帮助下爬行网页以获取与关键字相关的有意义内容的最佳方法是什么?

java - 如何解决我的构建错误?

java - ORA-01400 : Error while inserting Foreign Key using Hibernate

java - 使用 Java 8 过滤结果集的多个条件

java - Java 8 默认接口(interface)方法上的 Spring Integration @ServiceActivator

java - 将波动坐标写入文件

java - 为什么 Spring Security 和 Keycloak 收到 "Access is denied"错误?