Comment créer une instance d'interface anonyme dans Kotlin?

95

J'ai une bibliothèque Java tierce avec un objet avec une interface comme celle-ci:

public interface Handler<C> {
  void call(C context) throws Exception;
}

Comment puis-je l'implémenter de manière concise dans Kotlin similaire à la classe anonyme Java comme ceci:

Handler<MyContext> handler = new Handler<MyContext> {
   @Override
   public void call(MyContext context) throws Exception {
      System.out.println("Hello world");
   }
}

handler.call(myContext) // Prints "Hello world"
Peter Lamberg
la source

Réponses:

143

En supposant que l'interface ne dispose que d'une seule méthode, vous pouvez utiliser SAM

val handler = Handler<String> { println("Hello: $it") }

Si vous avez une méthode qui accepte un gestionnaire, vous pouvez même omettre les arguments de type:

fun acceptHandler(handler:Handler<String>){}

acceptHandler(Handler { println("Hello: $it") })

acceptHandler({ println("Hello: $it") })

acceptHandler { println("Hello: $it") }

Si l'interface a plus d'une méthode, la syntaxe est un peu plus verbeuse:

val handler = object: Handler2<String> {
    override fun call(context: String?) { println("Call: $context") }
    override fun run(context: String?) { println("Run: $context")  }
}
miensol
la source
2
acceptHandler { println("Hello: $it")}fonctionnerait également dans la plupart des cas
voddan
5
Pour quiconque lutte. je pense que l'interface doit être déclarée en java. Je pense que la conversion SAM ne fonctionne pas pour les interfaces kotlin. si c'est une interface kotlin, vous devez utiliser la méthode object: Handler {}. par ici: youtrack.jetbrains.com/issue/KT-7770 .
j2emanue
2
Vous pouvez le faire avec une interface Kotlin à partir de la version 1.4 - il vous suffit de la déclarer comme un fichier fun interface.
Nick le
18

J'ai eu un cas où je ne voulais pas créer de var pour cela mais le faire en ligne. La façon dont je l'ai réalisé est

funA(object: InterfaceListener {
                        override fun OnMethod1() {}

                        override fun OnMethod2() {}
})
Aalap
la source
14
     val obj = object : MyInterface {
         override fun function1(arg:Int) { ... }

         override fun function12(arg:Int,arg:Int) { ... }
     }
pruthwiraj.kadam
la source
2

La réponse la plus simple est probablement le lambda de Kotlin:

val handler = Handler<MyContext> {
  println("Hello world")
}

handler.call(myContext) // Prints "Hello world"
Peter Lamberg
la source