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更清洁。

如果你有这样的Java类

 recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new RecyclerTouchListener.ClickListener() { //Your Code })); 

你应该把这个代码从Java转换到Kotlin这样的:

 override fun showJozList (list : List) { adapter.addData(list) jozlist_recycler.addOnItemTouchListener(RecyclerTouchListener( activity , jozlist_recycler , object : RecyclerTouchListener.ClickListener { //Your Code })) 

转换Java接口

 new RecyclerTouchListener.ClickListener() 

Kotlin接口样式:

 object : RecyclerTouchListener.ClickListener