Interface as functions in Kotlin

This is called SAM-conversions,

Just like Java 8, Kotlin supports SAM conversions. This means that Kotlin function literals can be automatically converted into implementations of Java interfaces with a single non-default method, as long as the parameter types of the interface method match the parameter types of the Kotlin function.

But

Note that SAM conversions only work for interfaces, not for abstract classes, even if those also have just a single abstract method.
Also note that this feature works only for Java interop; since Kotlin has proper function types, automatic conversion of functions into implementations of Kotlin interfaces is unnecessary and therefore unsupported.

So, you can't write a simple Kotlin code to simulate this call.


In Java, if you write a

public interface Listener {
    void onEvent(); // SAM: Single Abstract Method. Only 1 is allowed
}

And you have a

public class SomeView extends FrameLayout {
    // skip the constructors

    public void setListener(Listener listener) {
        // do something
    }
}

Then you can do such a fancy call in Kotlin, thanks to SAM-conversion:

SomeView(this).setListener {} // asking a parameter with type () -> Unit for setListener
                              // Then parenthesis of function call can be omitted
// setListener function can also accept a parameter with type Listener
// by object : Listener {}

But if you convert that Java file into Kotlin, the code will report an error, due to the reason mentioned above. You have to implement a SomeView.setListener(() -> Unit) function by yourself, for example

fun SomeView.setListener(l: () -> Unit) {
    listener = object : Listener{
        override fun onEvent() {
            l()
        }
    }
}

You can define your interface as suggested and also add an extension that allows the usage of a lambda which is more idimatic for Kotlin code.

class SomeView {
    fun setListener(l: Listener) {}
}

fun SomeView.setListener(l: () -> Unit) = setListener(object : Listener {
    override fun onEvent() = l()
})

In Java, you would still be able to pass the Listener implementation.

Tags:

Android

Kotlin