0

I have a class that extends another class and implements an interface. The parent interface has a default method with the same signature as a method in the parent class, like below.

class ParentClass {
    public void doSomething(){
        System.out.println("Class method called");
    }
}

interface ParentInterface {
    default void doSomething(){
        System.out.println("Interface method called");
    }
}

class Child extends ParentClass implements ParentInterface {

}

At the moment, when doSomething() is called on an instance of the Child class, the version of the method from the parent class is run (Printing "Class method called"). However, I want the Child class to use the version of the method defined in the parent interface (Printing "Interface method called").

One way to do this is to override the doSomething() in the Child class and tell it to choose ParentInterface.super.doSomething() like so:

class Child extends ParentClass implements ParentInterface {
    public void doSomething() {
        ParentInterface.super.doSomething();
    }
}

Unfortunately, I have a lot of methods in ParentInterface and a lot of classes that implement ParentInterface and extend various classes that have their own version of the methods of ParentInterface. I've been very confused by some bugs because I was assuming a method call was going to ParentInterface when it was actually going to the parent class. In all cases, I would prefer if the default methods defined in the interface were always chosen over their corresponding methods from the class.

Is there some way that I can make my child classes default to using ParentInterface's methods without having to override each conflicting method in the child class?

  • I think you’re complicating things for yourself. Try to rethink the structure of your code. Avoid inheriting behavior. Try to use composition instead. See this question: https://stackoverflow.com/q/49002/11451 – Kristof Neirynck Jun 26 '22 at 16:14
  • 2
    No, the JLS clearly states that an implementation inherited from a parent class will always "win" over a default interface methods. That's also why default methods for `equals`, `hashCode` and `toString` aren't possible. – Rob Spoor Jun 26 '22 at 16:14
  • You might reasonably make a new subtype of ParentClass that is a subinterface of ParentInterface, do all the super. logic there, and subclass that instead of ParentClass. – Louis Wasserman Jun 26 '22 at 16:28

0 Answers0