Java Kotlin:接口......没有构造函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43737785/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Kotlin: Interface ... does not have constructors
提问by Aleph Aleph
I am converting some of my Java code to Kotlin and I do not quite understand how to instantiate interfaces that are defined in Kotlin code. As an example, I have an interface (defined in Java code):
我正在将我的一些 Java 代码转换为 Kotlin,但我不太明白如何实例化在 Kotlin 代码中定义的接口。例如,我有一个接口(在 Java 代码中定义):
public interface MyInterface {
void onLocationMeasured(Location location);
}
And then further in my Kotlin code I instantiate this interface:
然后在我的 Kotlin 代码中进一步实例化这个接口:
val myObj = new MyInterface { Log.d("...", "...") }
and it works fine. However, when I convert MyInterface to Kotlin:
它工作正常。但是,当我将 MyInterface 转换为 Kotlin 时:
interface MyInterface {
fun onLocationMeasured(location: Location)
}
I get an error message: Interface MyListener does not have constructors
when I try to instantiate it - though it seems to me that nothing has changed except syntax. Do I misunderstand how interfaces work in Kotlin?
我收到一条错误消息:Interface MyListener does not have constructors
当我尝试实例化它时 - 尽管在我看来除了语法没有任何改变。我是否误解了接口在 Kotlin 中的工作方式?
采纳答案by yole
Your Java code relies on SAM conversion - an automatic conversion of a lambda into an interface with a single abstract method. SAM conversion is currently not supportedfor interfaces defined in Kotlin. Instead, you need to define an anonymous object implementing the interface:
您的 Java 代码依赖于 SAM 转换 - 将 lambda 自动转换为具有单个抽象方法的接口。Kotlin 中定义的接口目前不支持SAM 转换。相反,您需要定义一个实现该接口的匿名对象:
val obj = object : MyInterface {
override fun onLocationMeasured(location: Location) { ... }
}
回答by Steven Spungin
The best solution is to use a typealias in-place of your Java interface
最好的解决方案是使用类型别名代替 Java 接口
typealias MyInterface = (Location) -> Unit
typealias MyInterface = (Location) -> Unit
fun addLocationHandler(myInterface:MyInterface) {
}
Register it like this:
像这样注册:
val myObject = { location -> ...}
addLocationHandler(myObject)
or even cleaner
甚至更干净
addLocationHandler { location -> ...}
Invoke it like this:
像这样调用它:
myInterface.invoke(location)
The 3 current options seem to be:
目前的 3 个选项似乎是:
- typealias (messy when called from java)
- kotlin interface (messy when called from kotlin; you need to create an object) This is a big step back IMO.
- java interface (less messy when called from kotlin; lambda needs interface name prepended so you don't need an object; also can't use lambda outside of function parenthesis convention)
- typealias(从java调用时混乱)
- kotlin 接口(从 kotlin 调用时很混乱;您需要创建一个对象)这是 IMO 的一大退步。
- java 接口(从 kotlin 调用时不那么混乱;lambda 需要在前面加上接口名称,因此您不需要对象;也不能在函数括号约定之外使用 lambda)
When converting our libraries to Kotlin, we actually left all the interfaces in Java code, as it was cleaner to call Java from Kotlin than Kotlin from Kotlin.
在将我们的库转换为 Kotlin 时,我们实际上将所有接口留在了 Java 代码中,因为从 Kotlin 调用 Java 比从 Kotlin 调用 Kotlin 更干净。
回答by Adnan Abdollah Zaki
if you have Java classlike this :
如果你有这样的Java 类:
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new RecyclerTouchListener.ClickListener()
{
//Your Code
}));
you shoud convert this code from Java to Kotlinlike this :
您应该像这样将此代码从 Java 转换为Kotlin:
override fun showJozList (list : List<ResponseGetJuzList.Parameter4>) {
adapter.addData(list)
jozlist_recycler.addOnItemTouchListener(RecyclerTouchListener(
activity ,
jozlist_recycler ,
object : RecyclerTouchListener.ClickListener
{
//Your Code
}))
convert Java Interface:
转换Java 接口:
new RecyclerTouchListener.ClickListener()
to Kotlin InterfaceStyle:
到科特林界面风格:
object : RecyclerTouchListener.ClickListener
回答by Jéw?m'
Try to access to your interface like this :
尝试像这样访问您的界面:
object : MyInterface {
override fun onSomething() { ... }
}
回答by Shin Seungwoo
If the interface is for a listener method of a class, change the interface definition to the function type. That makes the code more concise. See the following.
如果接口是用于类的侦听器方法,请将接口定义更改为函数类型。这使得代码更加简洁。请参阅以下内容。
Class containing listener definition
包含侦听器定义的类
// A class
private var mLocationMeasuredListener = (location: Location) -> Unit = {}
var setOnLocationMeasuredListener(listener: (location: Location) -> Unit) {
mLocationMeasuredListener = listener
}
// somewhere in A class
mLocationMeasuredListener(location)
Another class
另一堂课
// B class
aClass.setOnLocationMeasuredListener { location ->
// your code
}
回答by Braian Coronel
class YourClass : YourInterface {
override fun getTest() = "test"
}
interface YourInterface {
fun getTest(): String
}
val objectYourClass: YourInterface = YourClass()
print(objectYourClass.getTest())