Purpose of Default or Defender methods in Java 8
Asked Answered
A

5

48

Java 8 has included a new feature called Defender methods which allows creation of default method implementation in interface.

Now first of all this is a huge paradigm shift for all condensed programmers in Java. I viewed a JavaOne 13 presentation given by Brian Goetz where he was discussing about the new stream() and parallelStream() implementations in Collections library.

For adding new methods in Collection interface, they could not have just added a new method without breaking the previous versions. So he told that for catering this a new feature of Default methods was added.

public interface SimpleInterface {
  public void doSomeWork();
   
  //A default method in the interface created using "default" keyword
  default public void doSomeOtherWork(){
    System.out.println("DoSomeOtherWork implementation in the interface");
  }
}

Now my question is basically that are default methods just helpful when needed to add new methods to interface without breaking client code? Or are there some other uses to it too?

Amortization answered 15/11, 2013 at 9:59 Comment(5)
(Less dangerous) multiple inheritance; I have the same implimentation of the same interface all over my program because the implimenting classes extend different parent classes. This is going to reduce all that duplication into a single default methodSullivan
Java 8 : Default method in interfaceEugenie
@Richard: Java always had multiple inheritance of types. This extends that same mechanism to support multiple inheritance of behavior, while staying away from the very troublesome topic of multiple inheritance of state (which is where all the pain comes from.)Moro
@BrianGoetz Very good point about inheritance of state. I came to this thread because defender methods seemed a lot like multiple inheritance to me.Eagre
@RichardTingle it looks like you should have used composition to put that logic into a single place. And then specialize this class with inheritance if neededDevout
G
70

Besides having the possibility of adding methods to the interface in future versions, there is the important point of allowing an interface to stay a functional interface even if it has more than one method.

A functional interface has only one non-default abstract method which can be implemented via a lambda expression. One example is the Predicate interface which has only one abstract method (test) while providing default methods for negating a Predicate or combining it with another Predicate. Without default methods these methods had to be provided in another utility class like the pre-Java 8 Collections class (as you don’t want to give up the possibility of lambda implementations for such an interface).

Gertrudegertrudis answered 15/11, 2013 at 10:14 Comment(1)
up!!! Beside the above, if you programming by specification the default methods will saving lot of the abstract classes as possible.Impressionist
A
26

As you said, the main motivation was allowing the evolution of existing interfaces.

However there are reasons why you'd want to use them in brand new interfaces as well:

One such reason is methods that can easily be implemented using the other (non-default) methods of the interface. Using default methods for this reduces the need for Foo-interface/AbstractFoo-base-implementation combinations (see AbstractList for example).

While this does not create an entirely new field, it means that you can have end-user-friendly interfaces (with lots of useful methods), still keeping it simple to implement.

Anyway answered 15/11, 2013 at 10:2 Comment(9)
Isn't this somewhat of an hack? What do you think?Amortization
I personally have a "gut-feeling" that it's slightly imperfect, but I can't argue it. I supposed that's just unfamiliarity with this issue. In fact I also find them somewhat elegant in their own way as well.Anyway
What I do consider a hack is "expanding" an interface by adding methods in some other helper class (see Collections.*). Those are easy to do without a language change, but are called considerably different from interface methods and a concrete implementation can't change what they do (which leads to ugly marker interfaces like RandomAccess that indicate which algorithm to use for which class, even if they share a common interface).Anyway
@JoachimSauer do you say that sort for example should be on the Collection interfaces? Would not it result in binding the sort algorithm with the datastructure?Iggy
If you ever encountered a customer using an older JDBC driver than the JDK version required you really wished for default methods in the past even if they just threw UnsupportedOperationException (like the Iterator.remove method does now—at last)Gertrudegertrudis
@Iggy It’s the opposite, now the static sort method is always the same. With default methods, actual Collections could override it with an alternative algorithm optimized to the particular data structure. The method might still delegate to a static method in another class if you like it.Gertrudegertrudis
@JoachimSauer I see, that's a good point, but I still feel that algorithms should be separated from datastructures, that is, algorithms should be implemented in terms of abstract datatypes, so you can combine them as you need. I might be wrong though...Iggy
@Katona: yes, I understand, but sorting a linked list does give you quite a different set of options than sorting an array-list. While you might use the same general algorithm, you could optimize it for a linked list.Anyway
It's not a hack, primarily because you're still not able to store or use member data. Default methods provide a way to declare families of operations: provide the implementations for a couple of methods, and the rest become available as a beneficial side-effect. This ends up behaving similarly to traits from Scala or typeclasses from functional languages such as Haskell.Dozen
C
2

For adding new methods in Collection interface, they could not have just added a new method without breaking the previous versions.

Yes they could have done this but Let's think from API designer perspective for e.g. Collection Library is used by some libraries like apache-commons, guava etc and which instead are used by many java projects. Now imagine just by adding one new method in Collection interface will break entire chain of projects.

Now my question is basically that are default methods just helpful when needed to add new methods to interface without breaking client code? Or are there some other uses to it too?

Motivation/Need for Default Methods

API Evolution in compatible way

  • The initial purpose of introducing default methods was to make collections library backward compatible. This library was modelled as a deep hierarchy of interfaces, including prominent members such as Collection, List, Map, and Set. They needed to be enriched to make lambdas truly useful for everyday programming.

To make Collections library lambda rich, java architects could have refactored them to support lambda but it was a far from a good solution as it will break all the all existing Java deployments and countless 3rd party libraries extending the Collections hierarchy

Instead java architects thought to introduce default methods capabilities for backward compatibility.

Use cases of Default Methods

  • One important use case is to aid functional thinking in java. A functional interface with default methods is a pure behaviour-only construct. It cannot hold state. This aligns your thinking with functional programming and allows you to take advantage of what the programming model has to offer

  • Optional Methods : There are classes in java that implement an interface but leave empty method implementations for e.g. Iterator interface. It defines hasNext and next but also the remove method. Prior to Java8 remove was ignored because the user didn't want to use that capablity. Therefore many classes implementing Iterator interface would have empty implementation of for remove which is unnecessary boiler plate code. With default methods we can provide a default implementation for such methods, so concrete classes don't need to explicitly provide an empty implementation.

  • Default methods helps in resolving Multiple inheritance of behaviour in java. Before Java8, there was support for Multiple inheritance of Type only and now with the help of default methods we can have multiple inheritance of behaviour. For e.g. Java 8 has three rules for resolving conflicts brought upon by multiple inheritance when ambiguous:

    • First, an explicit method declaration in the class or a superclass takes priority over any default method declaration.
    • Otherwise, the method with the same signature in the most specific default providing interface is selected.
    • Finally, if there is still conflict, you have to explicitly override the default methods and choose which one your class should choose.

In Conclusion Default methods offer a brand new way to design objects.

References :

Java8 In Action

Functional Java: A Guide to Lambdas and Functional Programming in Java 8

Chemisorb answered 31/1, 2021 at 5:2 Comment(0)
S
1

There was a problem with interfaces that they were not open to extension, which means if there was a need to add new method to an interface it would have broken the existing implementation of these interfaces. Thus it was imperative that all the classes implementing that interface had to provide implementation for the newly added method, even if the method was not needed. Thus interfaces were not easy to evolve.

One example that comes to mind is Java MapReduce API for Hadoop, which was changed in 0.20.0 release to favour abstract classes over interfaces, since they are easier to evolve. Which means, a new method can be added to abstract class (with default implementation), with out breaking old implementations of the class.

With the release of Java 8, it is now possible to add default method in interfaces also, thus making them easier to evolve too. With the addition of default method to an interface, addition of new method, to even an interface will not break the pre-existing code.

Shoestring answered 5/5, 2015 at 17:11 Comment(0)
P
0
  1. default methods made possible the functional programming concept. For functional programming type code we need only one abstract method .
  2. Also adding an method in interface will not made it compulsory for all the classes implementing an interface. Simplified the coding practise
Placket answered 21/7, 2017 at 12:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.