在Java中显式调用默认方法

时间:2013-11-14 11:27:52

标签: java inheritance interface java-8 default-method

Java 8引入了default methods以提供扩展接口的能力,而无需修改现有的实现。

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

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

6 个答案:

答案 0 :(得分:257)

根据this article,您可以使用

访问界面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()的一部分方法。您还可以使用相同的语法来访问实现类中其他方法的默认版本。

方法调用语法的形式描述可以在chapter 15 of the JLS

中找到

答案 1 :(得分: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

答案 2 :(得分:5)

此答案主要面向来自问题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();
    }
}

<强>输出:

  

Hello ParentClass!
  你好InterfaceFoo!
  Hello InterfaceBar!

答案 3 :(得分:3)

您无需覆盖接口的默认方法。只需将其称为以下内容:

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

答案 4 :(得分:0)

是否要覆盖接口的默认方法取决于您的选择。因为 default 类似于类的实例方法,可以直接在实现类对象上调用。 (简而言之,接口的默认方法是通过实现类继承的)

答案 5 :(得分:0)

考虑以下示例:

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