Learn in Java
 


   

Java 8 - Functional Interfaces

 
A functional interface is any interface with only one method in it.

Remember:
Some real examples of functional interfaces in java api includes :
java.lang.Runnable with only a run() method
java.util.Comparator with only a compare() method

Note that the interface can include methods from object class like equals() hashCode() etc which are not considered as methods of the interface. In order for an interface to be called a functional interface, it must have defined methods of its own.

Java 8 has introduced a new annotation called @FunctionalInterface. This annotation is used to check for compile time type safety on functional interfaces. See the below example :

package com.learninjava;

/**
 * @author learninjava.com
 * @see www.learninjava.com
 */
public class FunctionalInterfaceExample1 {

	public static void main(String[] args) {
		
		// Call the method in functional interface directly
		FunctionalInterfaceExample1 functionalInterfaceExample1 = new FunctionalInterfaceExample1();
		// Since RedAngryBird is an inner class we will use the outer class instance
		RedAngryBird redAngryBird = functionalInterfaceExample1.new RedAngryBird();
		redAngryBird.hitThePig();

	}
	
	@FunctionalInterface
	public interface AngryBird {
		
		public void hitThePig();
		
	}

	class RedAngryBird implements AngryBird {
		
		public void hitThePig() {
			System.out.println("Hit the pig using Red Angry Bird...");
		}
	}
}

Output:
Hit the pig using Red Angry Bird...


 

In this example, there is a functional interface named AngryBird. This has only one method hitThePig(). RedAngryBird is a class that implements this interface and provides the implementation.

In the main() method, we tried calling the functional interface method using outer class instance. Dont get confused by the syntax, we are just calling the inner class(RegAngryBird) using the Outer class instance(functionalInterfaceExample1).

Now, where did we use the functional interface annotation. Well, the functional interface is already did its task, compile time type safety. It already checked to see if there is only one method in the interface or not. Since we had only one method all went well.

Let us try adding one more method to this interface and see what happens...

Try adding the below method to the AngryBird interface

    public void hitThePigAgain();
    

You will get the below compiler error:

Output:
Invalid '@FunctionalInterface' annotation; FunctionalInterfaceExample1.AngryBird is not a functional interface

What to learn:
A functional interface is an interface which can have one and only one method inside it.

Ok, now what if we have an interface which has more than one method in it but still lambda expressions could be used. Since we do not know what lambda expressions are yet, consider that we want to use only one method from a functional interface which has multiple methods. How to acheive this ?

The same challenge was faced by java api creators while extending collections api to support lambda expressions. To facilitate this, Java 8 has introduced default methods/defender methods/virtual extension methods. Consider the below example,

package com.learninjava;

/**
 * @author learninjava.com
 * @see www.learninjava.com
 */
public class FunctionalInterfaceExample2 {

	public static void main(String[] args) {
		
		// Call the method in functional interface directly
		FunctionalInterfaceExample2 functionalInterfaceExample = new FunctionalInterfaceExample2();
		// Since RedAngryBird is an inner class we will use the outer class instance
		RedAngryBird redAngryBird = functionalInterfaceExample.new RedAngryBird();
		redAngryBird.hitThePig();
		redAngryBird.hitThePigAgain();
	}
	
	@FunctionalInterface
	public interface AngryBird {
		
		public void hitThePig();
		
		// Adding method this way will result in a compiler error
		//public void hitThePigAgain();
		
		default public void hitThePigAgain() {
			System.out.println("Hit the pig using default Angry Bird...");
		}
	}

	class RedAngryBird implements AngryBird {
		
		public void hitThePig() {
			System.out.println("Hit the pig using Red Angry Bird...");
		}
	}
}

Output:
Hit the pig using Red Angry Bird...
Hit the pig using default Angry Bird...

From the above example, we can see that there is another method added to AngryBird called hitThePigAgain(). Observe the default keyword before the method declaration.

Remember:
Dont get confused between default access modifier and default keyword. 
Remember that default access modifier does not have any keyword. For example, 
the below method's access modifier is default and it is also a default/defender 
method.

default void hitThePigAgain() {
  System.out.println("Hit the pig using default Angry Bird...");
}

We will see a realtime usage of default method in Collections API while using Stream. For now, just remember that default method allows us to use the interface as a functional interface by providing default implementation.

Note that, by using default methods, we are actually adding implemenation to interface which are supposed to contain only abstract methods. Yes, from Java 8 onwards, interfaces can contain implementation via default methods.

 
   

Related Articles

Java 8 Stream
Java 8 Lambda Expressions
Equals and HashCode
 
   

Recommended Articles

User and Daemon Threads
Thread States
Restful WebService using CXF
Restful Client using CXF
SOAP WebService using CXF
SOAP Client using CXF




LIKE/SHARE
 
 
 
Download Source:

Comments:


 

Top Picks

1. Top 5 websites offering free e-books

2. Top 10 websites for free Java Articles and Tutorials

3. Top 5 websites for Java Certifications

4. Top 5 Softwares for Java developers




   
   
   
 
 
© Copyright 2017. All rights reserved. All trademarks and logos belongs to their owners.         Website Counter