Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why we need default methods in Java? [duplicate]

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?

like image 973
davioooh Avatar asked Sep 11 '14 09:09

davioooh


People also ask

Why do we need default methods in Java?

Default methods enable you to add new functionality to existing interfaces and ensure binary compatibility with code written for older versions of those interfaces. In particular, default methods enable you to add methods that accept lambda expressions as parameters to existing interfaces.

What happens if two interface have same default method?

A class implementation of a method takes precedence over a default method. So, if the class already has the same method as an Interface, then the default method from the implemented Interface does not take effect. However, if two interfaces implement the same default method, then there is a conflict.

Can we have 2 default method in interface?

Multiple Defaults With default functions in interfaces, there is a possibility that a class is implementing two interfaces with same default methods. The following code explains how this ambiguity can be resolved. First solution is to create an own method that overrides the default implementation.

Why do we need default and static methods in interface?

Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces. A static method is a method that is associated with the class in which it is defined rather than with any object.


3 Answers

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".

like image 121
Tim B Avatar answered Oct 03 '22 06:10

Tim B


There have been a lot of methods acting on an abstract interface in the past. Before Java 8 they had to be put into an additional class pairing the interface, e.g. Collections with Collection.

This old approach was neither more convincing than default methods nor more practical. Instead of list.sort() you had to say Collections.sort(list). This also implies that you had to make a fundamental decision when creating an interface, either you require every List implementation to implement a sort method or you provide a sort method in a utility class that cannot be overridden.

With default methods you can have both, a standard implementation which the List implementations do not need to implement on its own but still can be overridden if a concrete implementation has a more efficient way to do it knowing its internals, e.g. ArrayList.sort passes its internal array directly to Arrays.sort skipping some intermediate operations.

like image 40
Holger Avatar answered Oct 03 '22 08:10

Holger


Suppose at some point you want to add new functionality in declared interface, up to Java 7, If you will add a new method in declared an interface, you also have to define the implementation of the method in classes that are implementing that interface.

In java 8, You can add a default method containing the implementation and all the child class will inherit that method.

Edit : (After question update)

An interface represent a behaviour that a class MUST have

It still represent a behaviour that class must have, your confusion is how you are defining behaviour. All implementing class will inherit default method and are also free to write their own implementation. consider following two cases,

  1. If implementing class does not provide own implementation and simply inherit default method. If you change behaviour of default method in interface, implementing classes will be having updated behaviour as they inherit default method so it holds An interface represent a behaviour that a class MUST have.
  2. If implementing class provide own version of default method, and if you will change behaviour (only arguments) of default method. In this case implementing class will be having two overloaded methods, one which was earlier defined and second one is inherited default method. and if you change complete behaviour (arguments with return type also), It will create ambiguity in implementing class as you can not overload method by changing return type and Implementation will be broken. again it holds An interface represent a behaviour that a class MUST have.

Example :

Bulk data operation in collection is added in Java 8 (Reference : http://openjdk.java.net/jeps/107), to implement that forEach() method is added in Iterable interface. Adding abstract method in Iterable interface would break all the existing code because each class has to implement that method.

Solving the issue, following default forEach() method is added in Iterable interface,

interface Iterable 
{ 
   default void forEach(Consumer<? super T> action) 
   { 
      for (T t : this) action.accept(t); 
   } 
}

Reference : Java 8 : Default method in Interface

like image 32
Not a bug Avatar answered Oct 03 '22 07:10

Not a bug