1. What is Functional Interface
An interface with only one abstract method is called Functional Interface.
Pre Java 8, there was no concept of Functional Interface. However, interfaces like Comparator and Runnable have only one abstract method. Hence they fell into the Functional Interface category in Java 8 unintentionally.
2. Example
2.1 getSellingPrice method snippet from App.Java
package org.geekmj.java8;
public class App {
public static void main(String[] args) {
//
}
private static float getSellingPrice(float cost, float couponDiscount, DiscounterFunctionalInterface discounter) {
return cost - couponDiscount - discounter.discount(cost);
}
}
Here, we have a method getSellingPrice
, with three arguments cost
, couponDiscount
and discounter
. discounter
is of type DiscounterFunctionalInterface
. It calculates the selling price for an item.
2.2 DiscounterFunctionalInterface.java
package org.geekmj.java8;
@FunctionalInterface
public interface DiscounterFunctionalInterface {
public float discount(float cost);
}
Here, DiscounterFunctionalInterface is a functional interface with one abstract method discount
. The implementation of this method will calculate the discount for a given cost applying discount percentage.
2.3 App.java
package org.geekmj.java8;
public class App {
public static void main(String[] args) {
/* Discount for Cloth is 10% of cost */
System.out.println("Selling Price of Cloth Prices 200 after discount is " + getSellingPrice(200f, 0f, cost -> (cost * 10) / 100));
/* Discount for Book is 5% of cost */
System.out.println("Selling Price of Book Priced 150 after discount is " + getSellingPrice(150f, 10f, cost -> (cost * 5) / 100));
}
private static float getSellingPrice(float cost, float couponDiscount, DiscounterFunctionalInterface discounter) {
return cost - couponDiscount - discounter.discount(cost);
}
}
Here, in the main method, you had made a call to getSellingPrice
twice. You can see how we passed two different implementations of DiscounterFunctionalInterface using lambda expressions.
getSellingPrice(200f, 0f, cost -> (cost * 10) / 100)
getSellingPrice(150f, 10f, cost -> (cost * 5) / 100)
The compiler map the lambda expression signature with the discount method in DiscounterFunctionalInterface. It happens so because we have only one abstract method in DiscounterFunctionalInterface.
The above sample is also an example of Behaviour Parameterization or Execute Around Pattern using Lambda Expression.
3. Can you have multiple methods in Functional Interface?
Yes, you can have multiple methods in a Functional Interface. However, they can only be default methods.
4. Why it is Required?
Lambda Expression in Java 8 provides the ability to define a concise inline function that we can pass around.
In Java, we can pass Class and Primitive data types as an argument to a method.
Hence Java 8 Designer decided to introduce Functional Interface. Which will have only one abstract method. It allows the concise implementation of a Functional interface using Lambda expression. It further allowing lambda expression to pass around easily to methods.
Functional Interface is a simple design choice to represent Lambda Expression as an instance.
5. Function Descriptor
The description of the signature of the Lambda Expression is the same as the signature of the Functional Interface abstract method. Hence this abstract method is also called Function Descriptor.
6. @FunctionalInterface annotation
Most of the Functional Interfaces in Java 8 are annotated with @FunctionalInterface. However, it is not mandatory. But it is considered a good practice to use @FunctionalInterface.
7. Inbuilt Functional Interfaces in Java
In Java 8, we have several inbuilt Functional Interfaces that can be used by Lambda Expression readily. We will learn about them in another tutorial guide.
8. Source Code
Source code is available on GitHub for clone and download.
Please provide feedback for this article.