341

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?

GOTO 0
  • 42,323
  • 22
  • 125
  • 158

7 Answers7

468

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.

jihor
  • 2,478
  • 14
  • 28
Richard Tingle
  • 16,906
  • 5
  • 52
  • 77
  • 29
    Also note that if `A extends SomeOtherInterface`, and `SomeOtherInterface` has `default Type method()`, then you can't just call `SomeOtherInterface.super.method()` from ChildClass. You can only call default methods of interfaces enumerated in the `ChildClass`'s `implements` clause, not their parent interfaces' methods. – gvlasov May 25 '15 at 11:15
  • 1
    @Suseika good point, the same as there is no `super.super.someMethod();` (because that would be horrible) – Richard Tingle May 25 '15 at 11:18
  • 2
    @gvlasov good point , but how to access a parent interface's default method from a child interface , is it possible ?? Update.......... Yes Possible , the more concrete explanation here https://stackoverflow.com/a/24280376/3791156 – Raaghu Jan 02 '18 at 10:30
  • @RichardTingle flawless answer! – Gaurav Aug 08 '19 at 17:06
  • What is the rationale behind `Interface.super.method()`? Why not simply `Interface.method()`? – tejasvi88 Jun 10 '21 at 13:34
  • 1
    @tejasvi88 `Interface.method()` would imply a static method in `Interface`. It is a "kind of super" so the super part is arguably the most important – Richard Tingle Jun 10 '21 at 14:08
  • Also note, in this example, you cannot skip overriding `foo()` in `ChildClass` since it creates a conflict as both the interface has default implementation of same method. – Satrajit A Aug 10 '22 at 18:25
23

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

Output:

Hello ParentClass!
Hello InterfaceFoo!
Hello InterfaceBar!

Dávid Horváth
  • 4,050
  • 1
  • 20
  • 34
19

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
Neuron
  • 5,141
  • 5
  • 38
  • 59
Abhijith Nagarajan
  • 3,865
  • 18
  • 23
6

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

Neuron
  • 5,141
  • 5
  • 38
  • 59
Masudul
  • 21,823
  • 5
  • 43
  • 58
0

It depends on your choice whether you want to override the default method of an interface or not. Because default are similar to instance method of a class which can be directly called upon the implementing class object. (In short default method of an interface is inherited by implementing class)

Utpal Kumar
  • 425
  • 4
  • 11
0

Consider the following example:

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?
     }
}
Nomeswaran
  • 1,831
  • 2
  • 10
  • 7
0

Invoking default method of Java8 Functional Interface

@Functional Interface
interface Process {
   String preInit();
   default String postInit() {
       return "PostInit";
   }
}

public class ProcessImpl {
  Process process = () -> ("PreInit");
  String preInit = process.preInit();
  String postInit = process.postInit(); // Calling default method "postInit()" from functional interface
  System.out.println(preInit);
  System.out.println(postInit);
}

Output:
PreInit
PostInit