在Java中显式调用默认方法

GOT*_*O 0 217 java inheritance interface java-8 default-method

Java 8引入了默认方法,以提供扩展接口的能力,而无需修改现有实现.

我想知道,当该方法被覆盖或由于不同接口中的冲突默认实现不可用时,是否可以显式调用方法的默认实现.

interface A {
    default void foo() {
        System.out.println("A.foo");
    }
}

class B implements A {
    @Override
    public void foo() {
        System.out.println("B.foo");
    }
    public void afoo() {
        // how to invoke A.foo() here?
    }
}
Run Code Online (Sandbox Code Playgroud)

考虑到上面的代码,你会如何A.foo()从B类方法调用?

Ric*_*gle 283

根据本文,您可以在界面中A使用默认方法

A.super.foo();
Run Code Online (Sandbox Code Playgroud)

这可以如下使用(假设接口AC两者都有默认方法foo())

public class ChildClass implements A, C {
    @Override    
    public void foo() {
       //you could completely override the default implementations
       doSomethingElse();
       //or manage conflicts between the same method foo() in both A and C
       A.super.foo();
    }
    public void bah() {
       A.super.foo(); //original foo() from A accessed
       C.super.foo(); //original foo() from C accessed
    }
}
Run Code Online (Sandbox Code Playgroud)

A并且C可以都有.foo()方法,可以选择特定的默认实现,也可以使用一个(或两个)作为新foo()方法的一部分.您还可以使用相同的语法来访问实现类中其他方法的默认版本.

可以在JLS第15章中找到方法调用语法的形式描述.

  • 还要注意,如果`A扩展SomeOtherInterface`,并且`SomeOtherInterface`具有`默认的Type方法()`,那么你不能只从ChildClass调用`SomeOtherInterface.super.method()`.您只能调用`ChildClass`的`implements`子句中枚举的接口的默认方法,而不是它们的父接口方法. (13认同)
  • @gvlasov 好点,但是如何从子接口访问父接口的默认方法,这可能吗??更新.........是可能的,这里有更具体的解释 /sf/answers/1699626351/ (2认同)

Abh*_*jan 15

下面的代码应该有效.

public class B implements A {
    @Override
    public void foo() {
        System.out.println("B.foo");
    }

    void aFoo() {
        A.super.foo();
    }

    public static void main(String[] args) {
        B b = new B();
        b.foo();
        b.aFoo();
    }
}

interface A {
    default void foo() {
        System.out.println("A.foo");
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

B.foo
A.foo
Run Code Online (Sandbox Code Playgroud)


Dáv*_*áth 7

此答案主要是为来自问题45047550(已关闭)的用户编写的。

Java 8接口介绍了多重继承的某些方面。默认方法具有已实现的功能主体。要从超类调用方法,可以使用关键字super,但是如果要使用超接口来实现它,则需要显式命名它。

class ParentClass {
    public void hello() {
        System.out.println("Hello ParentClass!");
    }
}

interface InterfaceFoo {
    default public void hello() {
        System.out.println("Hello InterfaceFoo!");
    }
}

interface InterfaceBar {
    default public void hello() {
        System.out.println("Hello InterfaceBar!");
    }
}

public class Example extends ParentClass implements InterfaceFoo, InterfaceBar {
    public void hello() {
        super.hello(); // (note: ParentClass.super is wrong!)
        InterfaceFoo.super.hello();
        InterfaceBar.super.hello();
    }

    public static void main(String[] args) {
        new Example().hello();
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

家长班您好!
您好InterfaceFoo!
您好InterfaceBar!


Mas*_*dul 6

您不需要覆盖接口的默认方法。只需像下面这样调用它:

public class B implements A {

    @Override
    public void foo() {
        System.out.println("B.foo");
    }

    public void afoo() {
        A.super.foo();
    }

    public static void main(String[] args) {
       B b=new B();
       b.afoo();
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

福氏

  • OP 说:“当某个方法被重写时,[是否]可以显式调用该方法的默认实现” (11认同)