Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: Interface ... does not have constructors

Tags:

java

kotlin

I am converting some of my Java code to Kotlin and I do not quite understand how to instantiate interfaces that are defined in Kotlin code. As an example, I have an interface (defined in Java code):

public interface MyInterface {
    void onLocationMeasured(Location location);
}

And then further in my Kotlin code I instantiate this interface:

val myObj = new MyInterface { Log.d("...", "...") }

and it works fine. However, when I convert MyInterface to Kotlin:

interface MyInterface {
    fun onLocationMeasured(location: Location)
}

I get an error message: Interface MyListener does not have constructors when I try to instantiate it - though it seems to me that nothing has changed except syntax. Do I misunderstand how interfaces work in Kotlin?

like image 587
Aleph Aleph Avatar asked Oct 17 '22 08:10

Aleph Aleph


People also ask

CAN interface have constructor in Kotlin?

Interfaces cannot have constructors in Kotlin. Interfaces can have: declarations of abstract methods. method implementations.

Can Kotlin object have constructor?

In Kotlin, a class can have a primary constructor and one or more additional secondary constructors.

CAN interface have properties Kotlin?

Interfaces Interfaces in Kotlin can contain declarations of abstract methods, as well as method implementations. What makes them different from abstract classes is that interfaces cannot store state. They can have properties, but these need to be abstract or provide accessor implementations.


2 Answers

Your Java code relies on SAM conversion - an automatic conversion of a lambda into an interface with a single abstract method. SAM conversion is currently not supported for interfaces defined in Kotlin. Instead, you need to define an anonymous object implementing the interface:

val obj = object : MyInterface {
    override fun onLocationMeasured(location: Location) { ... }
}
like image 140
yole Avatar answered Oct 19 '22 02:10

yole


SAM conversion is supported for interfaces defined in Kotlin since 1.4.0

What's New in Kotlin 1.4.0

Before Kotlin 1.4.0, you could apply SAM (Single Abstract Method) conversions only when working with Java methods and Java interfaces from Kotlin. From now on, you can use SAM conversions for Kotlin interfaces as well. To do so, mark a Kotlin interface explicitly as functional with the fun modifier.

SAM conversion applies if you pass a lambda as an argument when an interface with only one single abstract method is expected as a parameter. In this case, the compiler automatically converts the lambda to an instance of the class that implements the abstract member function.

So the example in Your question will look something like this:

fun interface MyInterface {
    fun onLocationMeasured(location: String)
}

fun main() {
    val myObj = MyInterface { println(it) }

    myObj.onLocationMeasured("New York")
}
like image 22
iknow Avatar answered Oct 19 '22 01:10

iknow