Functional Interface in Kotlin
Tags: androiddev, kotlin, android
Published: 2024-04-01 17:23:37

## What is Functional Interface or SAM (Single Abstract Method)?

Functional Interface which is also known as Single Abstract Method (or SAM) is just an interface with only one abstract method (method without implementation).

## Representation

> Functional interfaces can be defined by putting a _fun_ modifier before the _interface_ keyword and it should only have one abstract method.

Let’s directly jump into the example to understand the details:

```Kotlin
// Normal Interface
interface ClickListener1 {
    fun onClick(view: View)
}

// Functional Interface or SAM (Single Abstract Method)
fun interface ClickListener2 {
    fun onClick(view: View)
}

class ClickUtil {

    private val view = View(null) //dummy view class just for the example

    private var clickListener1: ClickListener1? = null //normal interface
    private var clickListener2: ClickListener2? = null //functional interface
    private var clickListener3: ((View)->Unit)? = null //Higher order function

    fun setClickListener1(clickLis: ClickListener1) {
        clickListener1 = clickLis
    }

    fun setClickListener2(clickLis: ClickListener2) {
        clickListener2 = clickLis
    }

    fun setClickListener3(clickLis: (View)->Unit) {
        clickListener3 = clickLis
    }

    fun click1() {
        clickListener1?.onClick(view)
    }

    fun click2() {
        clickListener2?.onClick(view)
    }

    fun click3() {
        clickListener3?.invoke(view) //or clickListener(view), these are the only way to call the function
    }

}

fun main() {
    val clickUtil = ClickUtil()

    // In case of normal interface - Using anonymous object while passing to the function
    clickUtil.setClickListener1(object : ClickListener1 {
        override fun onClick(view: View) {
            // some click action
        }
    })

    // In case of Functional Interface - Using lambda while passing to the function
    clickUtil.setClickListener2 {view ->
        // some click action
    }

    // In case of Higher Order Function - Using lambda while passing to the function
    clickUtil.setClickListener3 {view ->
        // some click action
    }

}
```

In the above example, we have created basic example where we have three ways to represent basic clickListener:

1. **Normal Interface** — In first example, we have created normal interface (_ClickListener1_) with only one method (_onClick()_) and created the _setClickListener1_ function that take the object of _ClickListener1_ type. As _ClickListener1_ is an interface we need to use **anonymous object** while passing it.

2. **Functional Interface** — In second example, we have created functional interface (_ClickListener2_) with only one method (_onClick()_) and created the _setClickListener2_ function that take the object of _ClickListener2_ type. As _ClickListener2_ is an functional interface we can use **lambda expression** while passing it.

3. **Function Type** — In the third example, we directly used Kotlin Higher order function and use the lambda to pass the function.

## Why Functional Interface?

- It is clearly seen from example the reduction of boilerplate code when using functional interface, this makes code more concise and readable using lambda expression.

> **But main question is why not use Function types (Higher order function way) instead?**

Advantage of using Functional interface over function types:

- The function can be name differently that are being called (in our case _onClick()_), but in functional type it is always _invoke()_.

- Functional type can have only one member, while in case of functional interface we can add other non abstract methods as well. See below example:
```Kotlin
/*
- Extending the above example, adding print statement (non abstract method)
- Extending the functionality of Functional interface.
*/
fun interface ClickListener2 {
    fun onClick(view: View)
    fun clicked() {
        println("Clicked")
    }
}

fun click2() {
    clickListener2?.onClick(view)
    clickListener2?.clicked()
}
```

- Functional interfaces are optimized for primitive types as they have the advantage of not being wrapping types; that is, since a function type is a generic type at its core, primitives cannot be used with it. As a result, an input of type _Int_ will be converted to _Integer_ rather than _int_. For additional information about primitive type, see this [blog](https://medium.com/@khush.panchal123/does-kotlin-have-primitive-data-types-fe10b6daf78c).

### Contact Me:

[LinkedIn](https://www.linkedin.com/in/khush-panchal-241098170/), [Twitter](https://twitter.com/KhushPanchal15)

Happy Coding ✌️