• Software
  • Leadership
  • Agile
  • Events
  • Other Topics
    • Finance
    • Robotics & AI
    • System Administration
    • Books
    • Life Experiences
    • Environment
  • Write and Earn
  • About Us
    • About Us
    • Our Contributors
    • Contact Us
    • Article Submission Guidelines
    • Logo demystified
  • Follow @MeJaneve
    Janeve.Me
  • Categories

    Browse through following categories for articles written by professionals.
    • Agile
      4
    • Books
      5
    • Environment
      1
    • Events and Conferences
      7
    • Featured
      9
    • Finance
      1
    • Leadership
      6
    • Life Experiences
      8
    • Robotics & AI
      1
    • Software
      30
    • System Administration
      2
  • Software
  • Leadership
  • Agile
  • Events
  • Other Topics
    • Finance
    • Robotics & AI
    • System Administration
    • Books
    • Life Experiences
    • Environment
  • Write and Earn
  • About Us
    • About Us
    • Our Contributors
    • Contact Us
    • Article Submission Guidelines
    • Logo demystified
Home » Featured Software

Functional Interfaces in Java

Gunjan Talwar Posted On August 7, 2020
0
1.1K Views


0
Shares
  • Share On Facebook
  • Tweet It

A functional interface is an interface with only one abstract method thus exposing just one functionality.

Along with the only abstract method, a functional interface can contain any number of default methods.

The following code is an example of Functional Interface

@FunctionalInterface
public interface SampleFunctionalInterface {

  void sampleMethod(String input);

  default void sampleDefaultMethod(String input){
    System.out.println("Entered into the sampleDefaultMethod" + input);
  }
}

An interface with a single abstract method can be marked as a functional interface by adding the annotation ‘@FunctionalInterface’ over the interface name. This annotation will make sure that the compiler shows an ‘Unexpected @FunctionalInterface annotation’ when someone tries to add more than one abstract method. This annotation can save a programmer from accidentally introducing a second abstract method inside a functional interface. The @FunctionalInterface annotation is not mandatory and is a recommendation as it helps to avoid compilation errors in the code.

Functional interfaces were introduced in Java 8 along with Lambda. Together, lambda and functional interfaces, provide us a shorter way to implement functionalities without the need for creating full-blown classes and methods.

For example, before Java 8, a program to instantiate and start a thread would look like this –

class SampleThread {

  public static void main(String args[]) {
    Thread myThread = new Thread(new Runnable() {

    @override
    public void run() {
      System.out.println(“A new thread is started”);
    }
  }
  myThread.start();
  }
}

After Java 8 the whole code of instantiating a Thread’s object and starting it can be minimized into the following code snippet –

class SampleThread {

  public static void main(String args[]) {
    new Thread(() -> {System.out.println(“A new thread is started”);}).start();
  }
}

As seen in the SampleThread class above, we are using the Runnable functional interface which contains only one abstract method run(). Thus, we can instantiate a Thread object and start it using the Runnable functional interface and its abstract method run(), in just one line of the program.

So, how does the concept of Functional Interface deal with Java’s arch enemy ‘The Diamond problem’. As we all know that extending multiple classes in Java is not allowed because of the diamond problem.

Suppose for a while that extending multiple classes were allowed in Java, then if two classes; say class A and class B, that had a method with similar signatures, then the class extending these two classes will never know which method to use between the two parent classes. To avoid such a situation, multiple inheritances are forbidden in Java and it will throw a compile-time error. Consider the sample below for showcasing the compiler issue that Java throws in case of multiple inheritances –

First parent class, notice the method myUniqueMethod(int, String)

public class ParentClass1 {

  public String myUniqueMethod(int firstValue, String secondValue) {
    System.out.println("firstValue and secondValue are :"+firstValue+" & "+secondValue);
    return "From_ParentClass1";
  }
}

Second parent class, notice the same method with similar signature myUniqueMethod(int, String)

public class ParentClass2 {

  public String myUniqueMethod(int primaryArg, String secondaryArg) {
    System.out.println("primaryArg and secondaryArg are :"+primaryArg+" & "+secondaryArg);
    return "From_ParentClass2";
  }
}

Now let’s create a child class and see what happens when we try to extend both these parent classes –

public class ChildClass extends ParentClass1, ParentClass2 {

  public static void main(String args[]) {
    System.out.println("I am confused due to two parents with similar methods. "
    + "I won't let that happen!");
  }
}

If you are using an IDE then it will start highlighting an error over the extends keyword, as in my case of using Eclipse. The syntax errors thrown on Eclipse are –

Multiple markers at this line
  - Syntax error on token "extends", delete this token
  - Syntax error, insert "ClassBody" to complete

CompilationUnit
  - Syntax error, insert "}" to complete Block

This proves that multiple inheritances are prohibited in Java and trying to do which will cause syntax errors.

With the advent of default methods, there is a possibility of having a default method with a similar signature in two different interfaces and a child class implementing both these interfaces. How would the compiler know which parent class’ method to use? To avoid such a situation, it has been made mandatory to provide an implementation of the common default method of interfaces in the child class. So, the child class will have to implement the common default method found in multiple interfaces implemented by it.

Now revisiting the example shown above. Let’s consider ParentClass1 and ParentClass2 classes as interfaces and the child class implementing these interfaces. Here is how it would look now –

First parent interface –

public interface ParentInterface1 {

  public void doSomeStuff();

  public default String myUniqueMethod(int firstValue, String secondValue) {
    System.out.println("firstValue and secondValue are :"+firstValue+" & "+secondValue);
    return "From_ParentClass1";
  }
}

Second parent interface –

public interface ParentInterface2 {

  public String performSomeJob();

  public default String myUniqueMethod(int primaryArg, String secondaryArg) {
    System.out.println("primaryArg and secondaryArg are :"+primaryArg+" & "+secondaryArg);
    return "From_ParentClass2";
  }
}

The child class implementing the two interfaces with the common default methods would look like –

public class ChildClass implements ParentInterface1, ParentInterface2 {

  @Override
  public String performSomeJob() {
    System.out.println("Performing a job");
    return "PerformedSomeJob";
  }

  @Override
  public void doSomeStuff() {
    System.out.println("Doing some stuff");
  }

  public static void main(String args[]) {
    System.out.println("I am confused due to two parents with similar methods. "
    + "I won't let that happen!");
  }
}

In which case the IDE will complain about the missing implementation of the common default method by showing the below error –

Duplicate default methods named myUniqueMethod with the parameters (int, String) and (int, String) are inherited from the types ParentInterface2 and ParentInterface1

On compiling the ChildClass.java would throw an error with the message –

ChildClass.java:2: error: class ChildClass inherits unrelated defaults for myUniqueMethod(int,String) from types ParentInterface1 and ParentInterface2
public class ChildClass implements ParentInterface1, ParentInterface2 {
       ^
1 error

Adding the implementation for the common default method, myUniqueMethod(int, String), fixes the compilation error. Here is the ChildClass.java after implementing the common default method –

public class ChildClass implements ParentInterface1, ParentInterface2
{
  @Override
  public String performSomeJob() {
    System.out.println("Performing a job");
    return "PerformedSomeJob";
  }

  @Override
  public void doSomeStuff() {
    System.out.println("Doing some stuff");
  }

  @Override
  public String myUniqueMethod(int primaryArg, String secondaryArg) {
    return "my own uniqueMethod!";
  }

  public static void main(String args[]) {
    System.out.println("I am confused due to two parents with similar methods. " + "I won't let that happen!");
  }
}

To summarize, any interface with a single abstract method is a functional interface and its implementation can be used as a lambda expression. Optionally, a programmer can also enforce it to be a functional interface by using the @FunctionalInterface over the interface name while coding. In addition to the only abstract method, a functional interface can have any number of default methods. 

 

Post Views: 1,089
0
Shares
  • Share On Facebook
  • Tweet It




Author

Gunjan Talwar

A Software Engineer and a Java Programmer with 10+ years of experience in the Software Programming Industry. He has a strong affinity for Java language and Software Programming Skills.

The Java Stream API
Read Next

The Java Stream API

  • Follow @MeJaneve
    Janeve.Me
  • Categories

    Browse through following categories for articles written by professionals.
    • Agile
      4
    • Books
      5
    • Environment
      1
    • Events and Conferences
      7
    • Featured
      9
    • Finance
      1
    • Leadership
      6
    • Life Experiences
      8
    • Robotics & AI
      1
    • Software
      30
    • System Administration
      2

  • Popular Posts

  • Recent Posts

    • 3Es to Supercharge your Career Journey and Performance Review Ratings
    • Java Asynchronous Programming using CompletableFuture - Part 1
    • The Java Stream API
    • Functional Interfaces in Java
  • Keep In Touch

    Follow us on social media to get latest articles on Programming, System Architecture, Agile Development Methodologies, Product and Project Management, Personal Development, BigData, Robotics, Upcoming Events and more...


Copyright © 2020 | Janeve.Me. All rights Reserved.
Press enter/return to begin your search