Functional Interfaces are not a new concept in Java, it is just a normal interface with fewer modifications. So let get a little deeper into why functional interfaces are introduced in Java 8 and what are all the main differences between Regular Interfaces and these new Functional Interfaces.
Default Interface | Functional Interface |
Can have N number of Abstract Methods | Must have one abstract method |
Introduced in Java 1 | Introduced Java 8 |
It can have default /static methods | It can have default /static methods |
It can override abstract methods of Object Class | It also can override abstract methods of Object Class |
Does not Support Lambda Expressions | Support Lambda Expressions, Method reference, and constructor references |
Does not have an annotation to define the default interface. | It has an annotation named @FunctionalInterface |
Can I use Default Interfaces even in Java 8, The answer is Yes, you can use a regular interface in Java but you cant use these regular interfaces as Implementations in Lambda Expressions. Because Default interfaces can have multiple abstract methods, Lambda Expressions support only single abstract interfaces.
Functional Interfaces provides some satisfying feature for every developer and that is Code Optimization, These interfaces restrict unwanted pieces of code that we have used till Java 7, instead, we can Instantiate these Interfaces with a single line(That’s Lambda). Before Java 8 we used to define the Anonymous Class to do this logic.
The simple definition for Regular and Functional Interface
@FunctionalInterface interface Electric{ public void BateryPower(int a); } interface Diesel { void EnginePower(int a); }
Above the examples are the same but the Functional Interfaces are annotated by the annotation @FunctionalInterface, this indicates the interface is linked with the logics of Functional Interfaces.
But still, both Interfaces can be implemented by Lambda, See the below logic.
interface Hybrid { void EnginePower(int a); } Hybrid hybrid = (int a) -> { System.out.println("Hybrid Model Power Functional Interface : "+a); }; hybrid.EnginePower(5000);
Output :
Hybrid Model Power Functional Interface: 5000
In the above example, we did not mention the Interface type as Functional but still, the Interface can be used to implement Lambda Expressions. Then questions might rise like then what is the use of annotation here.
Check out the below example.
@FunctionalInterface interface Electric{ public void BateryPower(int a); public void Interiors(); } //This will not work, Compilation Error, Must have only one Abstract Method interface Electric{ public void BateryPower(int a); public void Interiors(); } //This works
In the above example, If we use more than one abstract method, the system throws an error. Compiles consider the Interface as FunctionalInterface because we explicitly mentioned the Interface as FunctionalInterface.
In the second example, we removed the annotation, and the program works, because the compiler did not consider the Interface as FunctionalInterface, and it cant be implemented by Lambda Expressions.
FunctionalInterfaces can have abstract methods of Object classes. check the below example.
interface Electric{ public void BateryPower(int a); public String toString() ; public boolean equals(Object obj) ; }
The above program runs without any problem because it contains one user-defined Abstract Method, two abstract methods of Object class.
FunctionalInterfaces are supporting default and static methods as regular interfaces.
See the below example.
@FunctionalInterface interface Electric{ public static void WheelBase(String a) {} public default void SeatMateria(String a) {} } interface Diesel { static void Windows() {} default void size() {} }
In the above example, both types of Interfaces are allowed to default and static methods.
Find the program to understand deeply,
package differencebetween; @FunctionalInterface interface Electric { public void BateryPower(int a); // public void Interiors(); //Returns Error,Multiple Abstract Method public String toString(); // Allowed, Not a Abstract from Interface, its comes from Object Class public boolean equals(Object obj); // Allowed, Not a Abstract from Interface, its comes from Object Class public static void WheelBase(String a) { System.out.println("This is Static Method of Functional Interface"); } // Static Method allowed public default void SeatMaterial(String a) { System.out.println("This is Default Method of Functional Interface : " + a); } // Default Method allowed } interface Diesel { void EnginePower(int a); void VehicleLength(int a);// Allowed, Multiple Abstract Methods void WheelBase(); static void Windows() { System.out.println("This is Static Method of Default Interface"); }// Static Method allowed default void size(String a) { System.out.println("This is Default Method of Default Interface : " + a); }// default Method allowed } interface Hybrid { void EnginePower(int a); } public class FunctionalInterfacesVsInterfaces { public static void main(String[] args) { Electric ev1 = (int a) -> { System.out.println("First Model Power Functional Interface : " + a); }; // Instantiating Functional interfaces using Lambda Electric ev2 = (int a) -> { System.out.println("Second Model Power Functional Interface : " + a); }; // One abstract instantiated into multiple ways ev1.BateryPower(1000); ev2.BateryPower(1100); ev1.SeatMaterial("Leather"); Diesel d = new Diesel() { public void EnginePower(int a) { System.out.println("Power default Interface : " + a); } public void WheelBase() { System.out.println("Wheelbase default Interface : "); } public void VehicleLength(int a) { // TODO Auto-generated method stub } }; // Need to Implement all the defined abstract methods d.EnginePower(2000); d.WheelBase(); d.size("450cm"); Hybrid hybrid = (int a) -> { System.out.println("Hybrid Model Power Functional Interface : " + a); }; // Instantiating Functional interfaces using Lambda hybrid.EnginePower(5000); } }
Output :
Second Model Power Functional Interface : 1100 This is Default Method of Functional Interface : Leather Power default Interface : 2000 Wheelbase default Interface : This is Default Method of Default Interface : 450cm Hybrid Model Power Functional Interface : 5000
Functional Interfaces were mainly Introduced in Java 8 to implement Lambda Expressions, Reason behind is Lambda in a Type of Inline Functionality to achieve this Functional Interface is the only way to accomplish. Functional Interfaces can be Instantiated by Lambda.