Котлин: интерфейс ... не имеет конструкторов



Я конвертирую некоторые из моих Java-кода в Kotlin, и я не совсем понимаю, как создавать экземпляры интерфейсов, которые определены в коде Kotlin. В качестве примера, у меня есть интерфейс (определенный в коде Java):



public interface MyInterface {
void onLocationMeasured(Location location);
}


а затем далее в моем коде Kotlin я создаю этот интерфейс:



val myObj = new MyInterface { Log.d("...", "...") }


и он отлично работает. Однако, когда я конвертирую свой интерфейс в Kotlin:



interface MyInterface {
fun onLocationMeasured(location: Location)
}


Я получаю сообщение об ошибке: Interface MyListener does not have constructors когда я пытаюсь создать его экземпляр, хотя это мне кажется, что ничего не изменилось, кроме синтаксиса. Я неправильно понимаю, как работают интерфейсы в Котлине?

949   4  

4 ответов:

ваш код Java основан на преобразовании SAM - автоматическом преобразовании лямбды в интерфейс с помощью одного абстрактного метода. Сэм преобразование в настоящее время не поддерживается для интерфейсов, определенных в Kotlin. Вместо этого необходимо определить анонимный объект, реализующий интерфейс:

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

лучшее решение-использовать typealias вместо вашего интерфейса Java

typealias MyInterface = (Location) -> Unit

fun addLocationHandler(myInterface:MyInterface) {

}

зарегистрируйте его следующим образом:

val myObject = { location -> ...}
addLocationHandler(myObject)

или еще лучше

addLocationHandler { location -> ...}

вызовите его так:

myInterface.invoke(location)

все 3 варианта могут быть:

  • typealias (грязный при вызове с java)
  • интерфейс kotlin (грязный при вызове из kotlin; вам нужно создать объект) это большой шаг назад ИМО.
  • интерфейс java (менее грязный при вызове из kotlin; лямбда-имя интерфейса должно быть добавлено, поэтому вам не нужен объект; также нельзя использовать лямбда вне соглашения о скобках функций)

при преобразовании наших библиотек в Kotlin мы фактически оставили все интерфейсы в Java-коде, так как было чище вызывать Java из Kotlin, чем Kotlin из Kotlin.

если у вас Java-класс такой :

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

вы должны преобразовать этот код из Java в Котлин такой :

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

преобразование Java-Интерфейс:

new RecyclerTouchListener.ClickListener()

до Котлин Интерфейс стиль:

object : RecyclerTouchListener.ClickListener

попробуйте получить доступ к вашему интерфейсу следующим образом:

 object : MyInterface {
    override fun onSomething() { ... }
}

Comments

    Ничего не найдено.