Edit Page

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.

fun interface KRunnable {
   fun invoke()
}

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:

fun interface IntPredicate {
   fun accept(i: Int): Boolean
}

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

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

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

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

A short lambda expression replaces all the unnecessary code.

fun interface IntPredicate {
   fun accept(i: Int): Boolean
}

val isEven = IntPredicate { it % 2 == 0 }

fun main() {
   println("Is 7 even? - ${isEven.accept(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.