Search code examples
javaprogramming-languagesjava-8

Why we need default methods in Java?


I'm taking a look to Java 8 news compared to 7 and in addition to very interesting things like lambdas or the new time framework, i found that a new feature(?) was introduced: default methods.

I found the following example in this article:

public interface Math {

    int add(int a, int b);

    default int multiply(int a, int b) {
        return a * b;
    }
}

It seems very strange to me. Above code looks like an abstract class with an implemented method. So, why to introduce default methods in an interface? What is the actual advantage of this approach?

In the same article I read this explaination:

Why would one want to add methods into Interfaces? We’ll it is because interfaces are too tightly coupled with their implementation classes. i.e. it is not possible to add a method in interface without breaking the implementor class. Once you add a method in interface, all its implemented classes must declare method body of this new method.

Well this doesn't convince me at all. IMHO I believe that when a class implements an interface obviosly must declare methods body for each method in it. This is surely a constraint, but it's also a confirm of its "nature" (if you understand what I mean...)

If you have common logic to every inheriting class you'll put it into an implementing abstract class.

So, what's the real advantage of a default method? (It looks more like a workaround than a new feature...)


UPDATE I understand that this approach is for backwards compatibility, but it still doesn't convince me so much. An interface represent a behaviour that a class MUST have. So a class implementing a certain interface has surely this behaviour. But if someone can arbitrarily change the interface, this constraint is broken. The behaviour can change anytime... Am I wrong?


Solution

  • This is for backwards compatibility.

    If you have an interface that other people have implemented then if you add a new method to the interface all existing implementations are broken.

    By adding a new method with a default implementation you remaining source-compatible with existing implementations.

    For a slightly simple/contrived example that should hopefully demonstrate this let us say you created a library:

    void drawSomething(Thing thing) {
    }
    
    interface Thing {
        Color getColor();
        Image getBackgroundImage();
    }
    

    Now you come to do a new version of your library and you want to add the concept of border colors, that's easy to add to the interface:

    interface Thing {
        Color getColor();
        Color getBorderColor();
        Image getBackgroundImage();
    }
    

    But the problem is that every single person using your library has to go back through every single Skin implementation they ever did and add this new method.

    If instead you provided a default implementation to getBorderColor that just called getColor then everything "just works".