Explicitly calling a default method in Java

允我心安 提交于 2019-11-26 00:42:45

问题


Java 8 introduces default methods to provide the ability to extend interfaces without the need to modify existing implementations.

I wonder if it\'s possible to explicitly invoke the default implementation of a method when that method has been overridden or is not available because of conflicting default implementations in different interfaces.

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

Considering the code above, how would you call A.foo() from a method of class B?


回答1:


As per this article you access default method in interface A using

A.super.foo();

This could be used as follows (assuming interfaces A and C both have default methods 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 and C can both have .foo() methods and the specific default implementation can be chosen or you can use one (or both) as part of your new foo() method. You can also use the same syntax to access the default versions in other methods in your implementing class.

Formal description of the method invocation syntax can be found in the chapter 15 of the JLS.




回答2:


The code below should work.

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

Output:

B.foo
A.foo



回答3:


This answer is written mainly for users who are coming from question 45047550 which is closed.

Java 8 interfaces introduce some aspects of multiple inheritance. Default methods has an implemented function body. To call a method from the super class you can use the keyword super, but if you want to make this with a super interface it's required to name it explicitly.

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

Output:

Hello ParentClass!
Hello InterfaceFoo!
Hello InterfaceBar!




回答4:


You don't need to override the default method of an interface. Just call it like the following:

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

Output:

A.foo



来源:https://stackoverflow.com/questions/19976487/explicitly-calling-a-default-method-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!