显式地调用Java中的默认方法

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?
}
}

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

90175 次浏览

您不需要重写接口的默认方法。就像这样称呼它:

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();
}
}

输出:

A.foo

根据这篇文章,你访问接口A中的默认方法使用

A.super.foo();

这可以如下使用(假设接口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
}
}

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

方法调用语法的正式描述可以在JLS的第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");
}
}

输出:

B.foo
A.foo

这个答案主要是为那些来自关闭的问题45047550的用户编写的。

Java 8接口引入了多重继承的一些方面。默认方法有一个实现的函数体。要从超类中调用方法,可以使用关键字super,但如果你想使用超接口,则需要显式地命名它。

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


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


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


public class Example extends ParentClass implements InterfaceFoo, InterfaceBar {
public void hello() {
super.hello(); // (note: ParentClass.super could not be used)
InterfaceFoo.super.hello();
InterfaceBar.super.hello();
}
    

public static void main(String[] args) {
new Example().hello();
}
}

输出:

< p >你好ParentClass !
你好InterfaceFoo !
你好InterfaceBar !< / p >

是否重写接口的默认方法取决于您的选择。因为默认方法类似于类的实例方法,可以在实现类对象时直接调用。(简而言之,接口的默认方法由实现类继承)

考虑下面的例子:

interface I{
default void print(){
System.out.println("Interface");
}
}


abstract class Abs{
public void print(){
System.out.println("Abstract");
}


}


public class Test extends Abs implements I{


public static void main(String[] args) throws ExecutionException, InterruptedException
{


Test t = new Test();
t.print();// calls Abstract's print method and How to call interface's defaut method?
}
}