Java 8 Default Methods Tutorial

Java 8 Default MethodsInterfaces in Java always contained method declaration not their definitions (method body). There was no way of defining method body / definition in interfaces. This is because historically Java didn’t allow multiple inheritance of classes. It allowed multiple inheritance of interfaces as interface were nothing but method declaration. This solves the problem of ambiguity in multiple inheritance. Since Java 8 it is now possible to add method bodies in interfaces.

Java 8 has a new feature called Default Methods. It is now possible to add method bodies into interfaces!

public interface Math {

	int add(int a, int b);

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

In above Math interface we added a method multiply with actual method body.

Why we need Default Methods?

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.

Since Java 8, things started getting ugly. A new feature Lambda was introduce which is cool. However it is not possible to use this feature in existing Java libraries such as java.util package. If you add a single method in interface List, it breaks everything. You need to add its implementation in every class that implements List interface. Imagine in real world how many custom classes would change.

So for backward compatibility, Java 8 cleverly added Default Methods.

Virtual Extension Methods

It added a new concept Virtual extension methods, or as they are often called defender methods, can now be added to interfaces providing a default implementation of the declared behavior. So existing interfaces can be augmented without compromising backward compatibility by adding extension methods to the interface, whose declaration would contain instructions for finding the default implementation in the event that implementors do not provide a method body. A key characteristic of extension methods is that they are virtual methods just like other interface methods, but provide a default implementation in the event that the implementing class does not provide a method body.

Consider following example:

interface Person {
	//adds a java 8 default method
	default void sayHello() {
		System.out.println("Hello there!");
	}
}

class Sam implements Person {

}

public class Main {
	
	public static void main(String [] args) {
		
		Sam sam = new Sam();
		
		//calling sayHello method calls the method
		//defined in interface
		sam.sayHello();
	}
}

Output:

Hello there!

In above code we added a defender method sayHello() in Person interface. So it was ok for class Sam to avoid declaring this methods body.

What about Multiple Inheritance?

Adding method definitions in interfaces can add ambiguity in multiple inheritance. isn’t it? Well, it does. However Java 8 handle this issue at Compile type. Consider below example:

interface Person {
	default void sayHello() {
		System.out.println("Hello");
	}
}

interface Male {
	default void sayHello() {
		System.out.println("Hi");
	}
}

class Sam implements Person, Male {

}

In this example we have same defender method sayHello in both interfaces Person and Male. Class Sam implements these interfaces. So which version of sayHello will be inherited? We’ll if you try to compile this code in Java 8, it will give following error.


class Sam inherits unrelated defaults for sayHello() from types Person and Male class Sam implements Person, Male { ^ 1 error

So that solves multiple inheritance problem. You cannot implement multiple interfaces having same signature of Java 8 default methods (without overriding explicitly in child class).

We can solve the above problem by overriding sayHello method in class Sam.

interface Person {
	default void sayHello() {
		System.out.println("Hello");
	}
}

interface Male {
	default void sayHello() {
		System.out.println("Hi");
	}
}

class Sam implements Person, Male {
	
	//override the sayHello to resolve ambiguity
	void sayHello() {
	
	}
}

It is also possible to explicitly call method from child class to parent interface. Consider in above example you want to call sayHello method from Male interface when Sam.sayHello is called. You can use super keyword to explicitly call the appropriate method.

class Sam implements Person, Male {
	
	//override the sayHello to resolve ambiguity
	void sayHello() {
		Male.super.sayHello();
	}
}

Difference between default methods and abstract class

Ok, so far it looks good. In Java 8 we can have concrete methods within interfaces.. right.. So how it is different from Abstract classes? Remember an abstract class is a class that can not be instantiated (i.e. objects can not be created of) and which may contain method bodies. Default method in Java 8 looks similar to Abstract class isn’t it?

We’ll its different actually. Abstract class can hold state of object. It can have constructors and member variables. Whereas interfaces with Java 8 default methods cannot hold state. It cannot have constructors and member variables. You should still use Abstract class whenever you think your class can have state or you need to do something in constructor. Default method should be used for backward compatibility. Whenever you want to add additional functionality in an existing legacy interface you can use default methods without breaking any existing implementor classes.

Also abstract classes cannot be root classes in Lambda expression. What?… I know that’s confusing, but Lambda expressions are the reason why virtual extension methods were introduced in Java 8. When a lambda expression is evaluated, the compiler can infers it into the interface where default method is added.



Tags: ,

20 Comments

  • Anju Singh 24 January, 2014, 11:36

    Its Totally new feature in Java.

    Thanks Viral for this excellent blog.

  • exex zian 24 January, 2014, 19:05

    nice tutorial and +1 for giving nice reasons by answering ” Why we need Default Methods? ” and ” Difference between default methods and abstract class “

  • Mohiadeen Jamil 27 January, 2014, 20:45

    Nice article. Thanks :)

  • Tousif Khan 28 January, 2014, 11:41

    Its really interesting and unique. Thanks Viral for sharing this. Looking forward to use it in Java8.
    You Rocks !

  • Manish Manker 30 January, 2014, 13:58

    Its a very fine feature that was needed to deal with multiple inheritance in Java.

    Thanks Viral.
    :-)

  • Satish Motwani 31 January, 2014, 13:59

    This is becoming more and more like C++ !! Java gained because it simplified. It is now going back the same path.

    What was the need for default methods. Say, if I want to add a new method “isHavingDuplicates()” to List. Instead of that, may I create a new interface IDuplicateDetectable (or any better name) with the new method and have the selected child classes implement this interface, and leave out the rest?

    Yes, they have given a feature. Use it if I like it, or ignore it. My point is that it introduces complexity to the language, and unexpected pitfalls.

    • Viral Patel 31 January, 2014, 15:59

      Hi Satish, Thanks for your comment. Creating a new interface IDuplicateDetectable and adding method isHavingDuplicates() looks certainly good. But it does not solve the problem. The idea of default methods makes sense when you look at it from Lambda expressions perspective. If you want to add new functionality to any existing class such as ArrayList etc is impossible without breaking the hierarchy. By adding default methods which can be used with Lambda expressions give all your child classes additional features.

  • Satish Motwani 31 January, 2014, 14:15

    >>> may I create a new interface IDuplicateDetectable (or any better name) with the new method and have the selected child classes implement this interface, and leave out the rest?

    I guess it is more useful for framework writers. I do get the point, if I think over it again :-)
    new interfaces for every new method you want to introduce will be a bad idea.

    But then, it would be very easy with IDEs like Eclipse to add a new method to interface and implement in all child classes. Where you do not want to implement, simply throw UnsupportedOperationException in the implementation of the interface.

    What is the “cost” of adding a feature vs its benefits. I somehow do not like the direction Java is taking.
    JSR 310 for date time is more needed in Core java than default methods. We have the alternative in Joda Time, but it runs into corporate project management bureaucracy even though it is Apache 2 licensed.

  • Gude Sreekanth 5 February, 2014, 12:33

    Nice Article yar… Daily i am reading your articles those are giving me to build confidence in java

    :-)

  • Antonio 12 March, 2014, 11:49

    Nice article. Great!!!!

  • Ramana 22 March, 2014, 23:08

    how to override ActionErrors reset method in struts??what are the rules we should follow for that???

  • Eyal 24 March, 2014, 20:19

    First, I think you gave a really good tutorial and explanation on the topic.

    In regard to this new feature, I am concerned about it.

    “…Default method should be used for backward compatibility. …”
    I can see the abuse of it of less-experienced developers.
    I guess a few years ago I would have over abused it my self.

    As people said before me, Java was designed for simplicity and tried to avoid ambiguity.
    This feature directs us to a too-much-sophisticated direction.

  • Sam 5 April, 2014, 8:00

    Nice explanation dude , u made it like a piece of cake.
    I found an interesting explanation here also , this guy explained in a funny way or i shud say comic way dats what he had given the title.
    http://lotusmediacentre.com/default-methods-in-java-8-explained/

    • Phanee 23 April, 2014, 12:53

      Thanks for the new link dude, Its very funny explination

  • FirstbloggerTricks.com 14 April, 2014, 13:19

    Really great introduction but I still have a question: why?
    Do lambda expressions add any performance increases
    or are they only good for impressing coworkers and confusing
    new comers? I don’t see how they’d make reading code any
    simpler and much, like the ternary operator, could just add
    to unreadability….

  • Rekha 23 April, 2014, 18:01

    great explanation.. I want small clarification, if there are already abstract classes defined for every interfaces then why we are using default methods in interface.?
    As you have given example of List interface, there is AbstractList interface class which already defined for that purpose so we can add default method in AbstractList class and we can use it anywhere.

  • Chris 16 May, 2014, 15:38

    Nice post Viral – I assume default methods cannot access object state (as no object variables are declared in the interface), so default methods are effectively static methods even though they are declared as object methods – is that correct?

  • sreekanth paatil 26 June, 2014, 12:29

    excelent tutorials..

  • Pankaj Lilhare 26 August, 2014, 17:43

    Nice Post!
    Thanks Viral.

  • Edward Beckett 29 September, 2014, 14:20

    Adding default methods to interfaces was a perfect example of how to solve a problem by adding another level of indirection…

Leave a Reply

Your email address will not be published. Required fields are marked *

Note

To post source code in comment, use [code language] [/code] tag, for example:

  • [code java] Java source code here [/code]
  • [code html] HTML here [/code]

Current ye@r *