¿Cómo crear una instancia de interfaz anónima en Kotlin?

95

Tengo una biblioteca Java de terceros que tiene un objeto con una interfaz como esta:

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

¿Cómo puedo implementarlo de manera concisa en Kotlin similar a la clase anónima de Java como esta?

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
fuente

Respuestas:

143

Suponiendo que la interfaz tiene solo un método, puede hacer uso de SAM

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

Si tiene un método que acepta un controlador, incluso puede omitir los argumentos de tipo:

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

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

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

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

Si la interfaz tiene más de un método, la sintaxis es un poco más detallada:

val handler = object: Handler2<String> {
    override fun call(context: String?) { println("Call: $context") }
    override fun run(context: String?) { println("Run: $context")  }
}
miensol
fuente
2
acceptHandler { println("Hello: $it")}también funcionaría en la mayoría de los casos
voddan
5
Para cualquiera que esté luchando. Creo que la interfaz debe declararse en java. Creo que la conversión de SAM no funciona para las interfaces de Kotlin. si es una interfaz de Kotlin, tienes que usar el objeto: Handler {} way. por aquí: youtrack.jetbrains.com/issue/KT-7770 .
j2emanue
2
Puede hacer esto con una interfaz de Kotlin a partir de 1.4; simplemente declare como un fun interface.
Nick
18

Tuve un caso en el que no quería crear una var para ello, sino hacerlo en línea. La forma en que lo logré es

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

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

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

La respuesta más simple probablemente sea la lambda de Kotlin:

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

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