【问题标题】:How to create an instance of anonymous interface in Kotlin?如何在 Kotlin 中创建匿名接口的实例?
【发布时间】:2016-10-06 22:08:45
【问题描述】:

我有一个第三方 Java 库,其中一个对象的接口如下:

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

如何在 Kotlin 中简洁地实现它,类似于这样的 Java 匿名类:

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"

【问题讨论】:

    标签: java lambda kotlin anonymous


    【解决方案1】:

    假设接口只有一个方法可以使用SAM

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

    从 1.4 版开始,Kotlin 支持 SAM 用于 Kotlin 中定义的接口。这需要在 interface 关键字前面加上 fun

    fun interface Handler<C> {
      fun call(context: C);
    }
    

    如果您有一个接受处理程序的方法,那么您甚至可以省略类型参数:

    fun acceptHandler(handler:Handler<String>){}
    
    acceptHandler(Handler { println("Hello: $it") })
    
    acceptHandler({ println("Hello: $it") })
    
    acceptHandler { println("Hello: $it") }
    

    如果接口有多个方法,则语法有点冗长:

    val handler = object: Handler2<String> {
        override fun call(context: String?) { println("Call: $context") }
        override fun run(context: String?) { println("Run: $context")  }
    }
    

    【讨论】:

    • acceptHandler { println("Hello: $it")} 在大多数情况下也可以使用
    • 对于任何挣扎的人。我认为接口必须在java中声明。我认为 SAM 转换不适用于 kotlin 接口。如果它是一个 kotlin 接口,你必须使用 object:Handler{} 方式。在这里:youtrack.jetbrains.com/issue/KT-7770 .
    • 您可以使用 Kotlin 1.4 接口来执行此操作 - 您只需将其声明为 fun interface
    • @Nick 我建议将其添加为单独的答案,或将其编辑到此答案中
    【解决方案2】:

    我有一个案例,我不想为它创建一个 var,而是内联。我实现它的方式是

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

    【讨论】:

      【解决方案3】:
           val obj = object : MyInterface {
               override fun function1(arg:Int) { ... }
      
               override fun function12(arg:Int,arg:Int) { ... }
           }
      

      【讨论】:

        【解决方案4】:

        从 Kotlin 1.4 开始,您可以声明一个函数式接口:

        fun interface Handler<C> {
          fun call(context: C);
        }
        

        然后你可以简洁地创建一个:

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

        Demo

        【讨论】:

          【解决方案5】:

          最简单的答案可能是 Kotlin 的 lambda:

          val handler = Handler<MyContext> {
            println("Hello world")
          }
          
          handler.call(myContext) // Prints "Hello world"
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-03-08
            • 1970-01-01
            • 2016-02-06
            • 1970-01-01
            • 2017-11-02
            • 1970-01-01
            • 1970-01-01
            • 2021-04-27
            相关资源
            最近更新 更多