Functional (SAM) interfaces

An interface with only one abstract method is called a functional interface, or a Single Abstract Method (SAM) interface. The functional interface can have several non-abstract members but only one abstract member.

To declare a functional interface in Kotlin, use the fun modifier.

  1. fun interface KRunnable {
  2. fun invoke()
  3. }

SAM conversions

For functional interfaces, you can use SAM conversions that help make your code more concise and readable by using lambda expressions.

Instead of creating a class that implements a functional interface manually, you can use a lambda expression. With a SAM conversion, Kotlin can convert any lambda expression whose signature matches the signature of the interface’s single method into an instance of a class that implements the interface.

For example, consider the following Kotlin functional interface:

  1. fun interface IntPredicate {
  2. fun accept(i: Int): Boolean
  3. }

If you don’t use a SAM conversion, you will need to write code like this:

  1. // Creating an instance of a class
  2. val isEven = object : IntPredicate {
  3. override fun accept(i: Int): Boolean {
  4. return i % 2 == 0
  5. }
  6. }

By leveraging Kotlin’s SAM conversion, you can write the following equivalent code instead:

  1. // Creating an instance using lambda
  2. val isEven = IntPredicate { it % 2 == 0 }

A short lambda expression replaces all the unnecessary code.

  1. fun interface IntPredicate {
  2. fun accept(i: Int): Boolean
  3. }
  4. val isEven = IntPredicate { it % 2 == 0 }
  5. fun main() {
  6. println("Is 7 even? - ${isEven.accept(7)}")
  7. }

You can also use SAM conversions for Java interfaces.

Functional interfaces vs. type aliases

Functional interfaces and type aliases serve different purposes. Type aliases are just names for existing types – they don’t create a new type, while functional interfaces do.

Type aliases can have only one member, while functional interfaces can have multiple non-abstract members and one abstract member. Functional interfaces can also implement and extend other interfaces.

Considering the above, functional interfaces are more flexible and provide more capabilities than type aliases.