Default, Defender or Extension Method of Java 8 with Example

Java 8 now allows you to add non-abstract method implementations to interfaces by utilizing the  default  and  static  keyword. Methods with default keyword are known as default methods or defender methods in Java. Before Java 8, it was virtually impossible to change an interface once published. Any change e.g. addition of a new method would have broken all clients. That's why when Java 8 decided to switch to internal  iterator implementation  using  forEach()  method, they face a daunting challenge of breaking all implementation of  Iterable  interface. Since backward compatibility is top priority for Java engineers, and it wasn't practical to break all clients, they came up with idea of  default method . This is an amazing and very powerful change, because now you can evolve your existing interface with all the knowledge you have gained after using them. JDK itself is utilizing default methods in big way,  java.util.Map  interface is extended with several new default methods e.g.  replaceAll() putIfAbsent(Key k, Value v)  and others. By the way, Since default method allows extension of  existing interface , it’s also known as  Extension method . You are also free to define any number of default method in your interface. I think after this change, you unlikely need an  abstract class  to provide skeletal implementation as described in Effective Java e.g.  List  comes with  AbstractList Collection  comes with AbstractCollection Set  comes with  AbstractSet  and  Map  comes with A bstractMap . Instead of creating a new abstract class with default implementation, you can define them as default method inside interface itself. Similarly, introduction of  static methods  inside interface will make pattern of an interface utility class redundant e.g.  Collections  for Collection interface,  Paths  for Path and so on. You can directly define static utility method on interface itself.



Java 8 Example of Default Methods

Java 8 enables us to add non-abstract method implementations to interfaces by utilizing the default keyword. This feature is also known as Extension Methods. Here is our first example:

interface Multiplication{
    int multiply(int a, int b);
   
    default int square(int a){
        return multiply(a, a);
    }
}

Besides the abstract method  multiply()  the interface  Multiplication  also defines the default method  square() . Any concrete classes of  Multiplication  interface only have to implement the  abstract method   multiply() . The default method  square()  method can be used directly.

   Multiplication  product  =   new   Multiplication (){
           
      @Override
      public int multiply(int x, int y){
          return x*y;
      }
  };
       
  int square = product.square(2);
  int multiplication = product.multiply(2, 3);

The product sub class is implemented using an anonymous class. The code is quite verbose : 6 lines of code for such a simple multiplication. You can reduce a lot of boiler plate code by using  lambda expression , which is also introduced on Java 8. Since our interface contains only one abstract method and Java's lambda expression is of SAM type (Single Abstract method), we can replace anonymous class implementation with just one line of lambda expression, as shown below :

Multiplication lambda = (x, y) -> x*y;
 
int product = lambda.multiply(3, 4);
int square = lambda.square(4);

Here is our complete Java program to demonstrate how you can use  default methods  inside interface in Java 8. As I said, now, you can even extend your old interface to add new methods without any fear of breaking clients, provided those methods must be either default or  static .


/**
* Java Program to demonstrate use of default method in Java 8.
 * You can define non-abstract method by using default keyword, and more
 * than one default method is permitted, which allows you to ship default skeletal
* implementation on interface itself.
*
* @author Javin Paul
*/
public class Java8DefaultMethodDemo{
 
    public static void main(String args[]) {
 
        // Implementing interface using Anonymous class
        Multiplication product = new Multiplication(){
           
            @Override
            public int multiply(int x, int y){
                return x*y;
            }
        };
       
        int squareOfTwo = product.square(2);
        int cubeOfTwo = product.cube(2);
 
        System.out.println("Square of Two : " + squareOfTwo);
        System.out.println("Cube of Two : " + cubeOfTwo);
       
        // Since Multiplication has only one abstract method, it can
        // also be implemented using lambda expression in Java 8
       
        Multiplication lambda = (x, y) -> x*y;
       
        int squareOfThree = lambda.square(3);
        int cubeOfThree = lambda.cube(3);
       
        System.out.println("Square of Three : " + squareOfThree);
        System.out.println("Cube of Three : " + cubeOfThree);
       
    }
 
}
 
interface Multiplication{
    int multiply(int a, int b);
   
    default int square(int a){
        return multiply(a, a);
    }
   
    default int cube(int a){
        return multiply(multiply(a, a), a);
    }
}
Output :
Square of Two : 4
Cube of Two : 8
Square of Three : 9
Cube of Three : 27

This code is an excellent example of how you can use default methods to add convenient methods on interface itself. This is also an example of template method pattern and avoids an extra helper class e.g. Collections, which just provide utility method to work on Collection. You can now define such methods in the Collection class itself. In this example of Java 8 default method, we have an interface Multiplication, which has its core abstract method called  multiply(a, b) , which supposed to multiply two numbers. It has then create two concrete method using default keyword, called  square(a)  and  cube(a) , which depends upon  multiply(a, b)  method for their function. Now, client just need to implement  multiply( ) method, and he will get both  square(a)  and  cube(a)  for free.


Important points about Java 8 Default Methods

Default and Defender Method of Java 8 with Example
Now it's time to revise whatever we have learned so far and note down some of the important things about our new defender, extension or default method of Java 8. You can take away all the knowledge in form of these bullet points. It's not only help you to quickly revise the topic but also encourage you to explore further and discover more about those individual things.

1) You can add default methods either on new interface or existing methods, provided they are compiled using source version of Java 8.

2) Default methods has blurred  difference between abstract class and interface in Java . So next time while answering this question on interview, don't forget to mention that you can do some of the things which was only possible with abstract class using default keyword. You can now define concrete methods on interfaces with the help of default methods.

3)  default  is not a new keyword, instead it was reserved form JDK 1.1 for these kind of evolution.

4) You are free to define any number of default methods in your interface. There is no restriction on number of default method an interface can contain in Java 8.

5) If an interface let's say C, extend two interfaces A and B, which has default method with same name and signature then compiler will complain about this while compiling class C. It's not allowed in Java 8 to avoid ambiguity. So even after default methods,  multiple inheritance is still not allowed in Java 8 . You cannot extend multiple interface with conflicting Java interface default method implementation.

6) There are lot of examples of Java 8 interface default methods are available in JDK 1.8 code base, one of the most popular one is  forEach()  method. You can also open interfaces like  java.util.Map  to see new default methods e.g.  putIfAbsent() , which was only available to  ConcurrentMap  prior to JDK 1.8 version.


That's all about  default methods of Java 8 . This is one of the breakthrough change, which will open path for better and more convenient interfaces. Best way to remember default method is to remember problem of using  putIfAbsent()  method of  ConcurrentMap  from JDK 1.7, which was not present in Map. It was not possible to write methods which can directly operate on Map interface because any time if a Map interface points to a  ConcurrentMap  object, you need to cast into ConcurrentMap  just for sake of using  putIfAbsent()  method. With extension methods, now JDK 8's  java.util.Map  interface has got its own  putIfAbsent()  method.

Reference: http://javarevisited.blogspot.sg/2014/07/default-defender-or-extension-method-of-Java8-example-tutorial.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值