Java 8 - Functional Interface vs Abstract class

But my doubt is, this what abstract class is for.

Why introduce functional interfaces.

Number of classes that can be extended: 1

Number of interfaces that can be implemented: more than 1


Functional interface are is used in a "safe" multiple inheritance. Differences:

  • A class may extend multiple functional interfaces.
  • Functional interfaces may have only a single abstract method.
  • Functional interfaces may not have fields unlike C++ abstract classes.

Typical usage is when you want to embed default functionality into objects. I.e. if you have a function-like object,

class MyFunction1 {
    public Integer apply(String s){
        ...
    }
}

class MyFunction2 {
    public List<String> apply(Integer s){
        ...
    }
}

And you want to make a composition out of them, you just drop in implements Function:

class MyFunction1 implements Function<String, Integer>{
    public Integer apply(String s){
        ...
    }
}

class MyFunction2 implements Function<Integer, List<String>>{
    public List<String> apply(Integer s){
        ...
    }
}

And you may create a composition of your functions. Two approaches compared:

No functional interfaces:

MyFunction1 myFunction1 = ...;
MyFunction2 myFunction2 = ...;

Function<String, List<String>> composition = (s) -> myFunction2.apply(myFunction1.apply(s));

With functional interfaces:

MyFunction1 myFunction1 = ...;
MyFunction2 myFunction2 = ...;

Function<String, List<String>> composition = myFunction1.andThen(myFunction2);

The difference

  • No need to re-implement functions.
  • Other functions available in the extending class: compose and identity.
  • New default function is made a part of a class hierarchy and there is no need to create a new object. Usually functions like compose() are not included into a class definition as it would result into class size growth. They are often put into separate utility classes. In Guava composition is put into a separate utility class Functions: Functions.compose. So with new functional interfaces you would not need to recall in which utility class your function is implemented.