我正在将我的一些Java代码转换为Kotlin,我不太了解如何实例化Kotlin代码中定义的接口.作为一个例子,我有一个接口(在Java代码中定义):
public interface MyInterface {
void onLocationMeasured(Location location);
}
Run Code Online (Sandbox Code Playgroud)
然后在我的Kotlin代码中进一步实例化这个接口:
val myObj = new MyInterface { Log.d("...", "...") }
Run Code Online (Sandbox Code Playgroud)
它工作正常.但是,当我将MyInterface转换为Kotlin时:
interface MyInterface {
fun onLocationMeasured(location: Location)
}
Run Code Online (Sandbox Code Playgroud)
我收到一条错误消息:Interface MyListener does not have constructors
当我尝试实例化它时 - 虽然在我看来除了语法之外没有任何改变.我是否误解了Kotlin界面的工作原理?
yol*_*ole 186
您的Java代码依赖于SAM转换 - 使用单个抽象方法将lambda自动转换为接口.目前 Kotlin中定义的接口不支持 SAM转换.相反,您需要定义实现接口的匿名对象:
val obj = object : MyInterface {
override fun onLocationMeasured(location: Location) { ... }
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*gin 16
最好的解决方案是使用Java接口的类型
typealias MyInterface = (Location) -> Unit
fun addLocationHandler(myInterface:MyInterface) {
}
Run Code Online (Sandbox Code Playgroud)
像这样注册:
val myObject = { location -> ...}
addLocationHandler(myObject)
Run Code Online (Sandbox Code Playgroud)
甚至更清洁
addLocationHandler { location -> ...}
Run Code Online (Sandbox Code Playgroud)
像这样调用它:
myInterface.invoke(location)
Run Code Online (Sandbox Code Playgroud)
目前的3种选择似乎是:
在将我们的库转换为Kotlin时,我们实际上将所有接口都保留在Java代码中,因为从Kotlin调用Java比从Kotlin调用Kotlin更简洁.
Kotlin 中定义的接口支持 SAM 转换,因为 1.4.0
在 Kotlin 之前
1.4.0
,您只能在使用 Kotlin 的Java 方法和 Java 接口时应用 SAM(单一抽象方法)转换。从现在开始,您也可以对 Kotlin 接口使用 SAM 转换。为此,请使用fun
修饰符将 Kotlin 接口显式标记为具有功能性。
如果您将 lambda 作为参数传递,而预期只有一个抽象方法的接口作为参数,则 SAM 转换适用。在这种情况下,编译器会自动将 lambda 转换为实现抽象成员函数的类的实例。
所以你的问题中的例子看起来像这样:
fun interface MyInterface
{
fun onLocationMeasured(location: String)
}
fun main()
{
val myObj = MyInterface { println(it) }
myObj.onLocationMeasured("New York")
}
Run Code Online (Sandbox Code Playgroud)
如果您有这样的Java类:
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new RecyclerTouchListener.ClickListener()
{
//Your Code
}));
Run Code Online (Sandbox Code Playgroud)
你应该把这个代码从Java转换成Kotlin,如下所示:
override fun showJozList (list : List<ResponseGetJuzList.Parameter4>) {
adapter.addData(list)
jozlist_recycler.addOnItemTouchListener(RecyclerTouchListener(
activity ,
jozlist_recycler ,
object : RecyclerTouchListener.ClickListener
{
//Your Code
}))
Run Code Online (Sandbox Code Playgroud)
转换Java接口:
new RecyclerTouchListener.ClickListener()
Run Code Online (Sandbox Code Playgroud)
到Kotlin界面风格:
object : RecyclerTouchListener.ClickListener
Run Code Online (Sandbox Code Playgroud)
尝试像这样访问您的界面:
object : MyInterface {
override fun onSomething() { ... }
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
28414 次 |
最近记录: |