Kotlin:接口......没有构造函数

新手上路,请多包涵

我正在将我的一些 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)
}

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

原文由 Aleph Aleph 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 712
2 个回答

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

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

原文由 yole 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

Kotlin 的新 1.4.0

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

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

所以你的问题中的例子看起来像这样:

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

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

    myObj.onLocationMeasured("New York")
}

原文由 iknow 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题