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() ?


当前回答

考虑下面的例子:

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

其他回答

考虑下面的例子:

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

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

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

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

可以这样使用(假设接口A和C都有默认方法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
    }
}

A和C都可以有.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