171 votes

Kotlin: Interface ... n'a pas de constructeur

Je suis la conversion d'une partie de mon code Java de Kotlin et je ne comprends pas très bien comment instancier les interfaces qui sont définis dans Kotlin code. Comme un exemple, j'ai une interface (au sens défini dans le code Java):

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

Et puis plus loin dans mon Kotlin code que j'ai instancier cette interface:

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

et il fonctionne très bien. Cependant, quand je convertir MyInterface de Kotlin:

interface MyInterface {
    fun onLocationMeasured(location: Location)
}

Je reçois un message d'erreur: Interface MyListener does not have constructors lorsque j'essaie d'instancier - mais il me semble que rien n'a changé à l'exception de la syntaxe. Dois-je mal comprendre la façon dont les interfaces de travail dans Kotlin?

269voto

yole Points 3628

Votre code Java repose sur la conversion SAM - une conversion automatique d'un lambda en une interface avec une seule méthode abstraite. La conversion SAM n'est actuellement pas prise en charge pour les interfaces définies dans Kotlin. Au lieu de cela, vous devez définir un objet anonyme implémentant l'interface:

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

20voto

Steven Spungin Points 5660

La meilleure solution est d'utiliser un typealias en place de votre interface Java

typealias MyInterface = (Location) -> Unit

fun addLocationHandler(myInterface:MyInterface) {

}

Inscrire de cette façon:

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

ou même plus propre

addLocationHandler { location -> ...}

L'appeler comme ceci:

myInterface.invoke(location)

Les 3 options actuelles semblent être:

  • typealias (salissant, lorsqu'il est appelé à partir de java)
  • kotlin interface (en désordre, lorsqu'il est appelé à partir de kotlin; vous devez créer un objet) C'est un grand pas en arrière de l'OMI.
  • l'interface java (moins salissant, lorsqu'il est appelé à partir de kotlin; lambda besoins nom de l'interface avant de sorte que vous n'avez pas besoin d'un objet; aussi ne peut pas utiliser lambda à l'extérieur de la fonction entre parenthèses convention)

Lors de la conversion de nos bibliothèques de Kotlin, nous avons laissé toutes les interfaces dans le code Java, il était plus propre à l'appel de Java à partir de Kotlin de Kotlin de Kotlin.

14voto

Jéwôm' Points 1209

Essayez d'accéder à votre interface comme ceci:

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

8voto

si vous avez une classe Java comme ceci:

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

vous devriez convertir ce code de Java à Kotlin comme ceci:

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

convertir l'interface Java :

 new RecyclerTouchListener.ClickListener()
 

au style d' interface Kotlin :

 object : RecyclerTouchListener.ClickListener
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X