Kotlin: Interface ...没有构造函数

2022-08-31 06:55:53

我正在将我的一些Java代码转换为Kotlin,我不太了解如何实例化在Kotlin代码中定义的接口。例如,我有一个接口(在Java代码中定义):

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

然后在我的 Kotlin 代码中,我进一步实例化了这个接口:

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

它工作正常。但是,当我将 MyInterface 转换为 Kotlin 时:

interface MyInterface {
    fun onLocationMeasured(location: Location)
}

我收到一条错误消息:当我尝试实例化它时 - 尽管在我看来,除了语法之外没有任何变化。我是否误解了 Kotlin 中的接口工作方式?Interface MyListener does not have constructors


答案 1

您的 Java 代码依赖于 SAM 转换 - 使用单个抽象方法将 lambda 自动转换为接口。Kotlin 中定义的接口目前不支持 SAM 转换。相反,您需要定义一个实现接口的匿名对象:

val obj = object : MyInterface {
    override fun onLocationMeasured(location: Location) { ... }
}

答案 2

1.4.0 起,Kotlin 中定义的接口支持 SAM 转换

Kotlin 1.4.0 中的新增功能

在 Kotlin 之前,您只能在使用 Kotlin 中的 Java 方法和 Java 接口时应用 SAM(单抽象方法)转换。从现在开始,您也可以将 SAM 转换用于 Kotlin 接口。为此,请使用 fun 修饰符将 Kotlin 接口显式标记为函数式。1.4.0

如果将 lambda 作为参数传递,则 SAM 转换适用,而只有一个抽象方法的接口需要作为参数。在这种情况下,编译器会自动将 lambda 转换为实现抽象成员函数的类的实例。

因此,您的问题中的示例将如下所示:

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

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

    myObj.onLocationMeasured("New York")
}

推荐