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中的接口是如何工作的吗?
您的Java代码依赖于SAM转换 – 使用单个抽象方法将lambda自动转换为接口。 Kotlin中定义的接口目前不支持 SAM转换。 相反,您需要定义一个实现该接口的匿名对象:
val obj = object : MyInterface { override fun onLocationMeasured(location: Location) { ... } }
最好的解决方案是在你的Java接口中使用一个typealias
typealias MyInterface = (Location) -> Unit
fun addLocationHandler(myInterface:MyInterface) { }
这样注册:
val myObject = { location -> ...} addLocationHandler(myObject)
甚至更干净
addLocationHandler { location -> ...}
像这样调用它:
myInterface.invoke(location)
目前的三种选择似乎是:
- typealias(从java调用时是乱七八糟的)
- kotlin界面(当从kotlin调用时,你需要创建一个对象);这是IMO的一大步。
- java接口(从kotlin调用时较少杂乱; lambda需要接口名称,所以你不需要一个对象;也不能使用函数括号约定外的lambda)
当把我们的库转换成Kotlin时,我们实际上把所有的接口留在了Java代码中,因为从Kotlin调用Java比Kotlin的Kotlin更清洁。