This feature will be coming Kotlin 1.4
. Here is an excerpt from KotlinConf'19
.
fun interface Action {
fun run()
}
fun runAction(a: Action) = a.run()
runAction{
println("Hello")
}
It looks nice, but I still don't know what it does.
What is the function interface? What is its practical value? What specific scenarios can it be used for?
Unlike earlier version of Java8, Kotlin can have default implementation in interface.
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.
A functional interface is an interface that contains only one abstract method. They can have only one functionality to exhibit. From Java 8 onwards, lambda expressions can be used to represent the instance of a functional interface. A functional interface can have any number of default methods.
Kotlin allows Interface to have code which means a class can implement an Interface, and inherit the behavior from it. After using Kotlin in Android development for a while, I've just realized the benefit of Interface in Kotlin.
This is about functional interfaces — interfaces with a Single Abstract Method (also called SAM interfaces).
To understand the point, I'll need to cover a little history… In Java, lambdas were added relatively recently. Before that, you implemented callbacks and similar by implementing a suitable interface. For example, if you wanted to be informed when an AWT component was actioned, you'd create an object which implemented the ActionListener
interface. That has a single method (called actionPerformed()
); you'd put your code inside that method:
myButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Do something
}
});
When they added lambdas, they wanted to blend in with all the existing code, and change as little as possible, so they did it exactly the same way: the compiler infers which interface you're implementing, and creates an object implementing that interface. You could write:
myButton.addActionListener(e -> {
// Do something
});
which is shorter — but it compiles down to pretty much the same as the first example.
So in Java, functions are not first-class objects; lambdas are simply a more concise way to implement functional interfaces.
In Kotlin, however, functions are first-class objects: you can write a lambda (or an anonymous function) on its own, assign it, pass it to functions, return it from functions, and so on — so there's no need for SAM interfaces at all!
For easier interoperability with Java, Kotlin lets you easily implement Java SAM interfaces, in the same way you do from Java:
myButton.addActionListener {
// Do something
}
But Kotlin <= 1.3 doesn't let you implement Kotlin interfaces that way; you need to implement those explicitly. (I suspect this was partly to encourage developers to use proper functions, with all their other advantages, and not rely on the Java-style workaround.)
Your example illustrates this. It has an interface (Action
) with one abstract method (run()
). It has a function (runAction()
) which takes an instance of that interface. And it has some code which wants to call that function, passing just the code for the run()
method.
In Kotlin <= 1.3, you'd have to do the latter explicitly, e.g.:
runAction(object : Action {
override fun run() {
println("Hello")
}
})
But from Kotlin 1.4, you can mark the interface as fun interface
, and use the Java-style shortcut, as in your example.
(You may or may not think this is a good thing…)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With