Kotlin中的sam(函数式接口)详解

 更新时间:2019年03月17日 11:00:06   作者:Android架构  
这篇文章主要介绍了Kotlin中的sam(函数式接口)详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

用lambda表达式去表示java中的匿名类实例

在使用java去给一个按钮设置监听我们通常会通过创建匿名类实例,如下

Button.setOnClickListener(new OnClickListener()){
  @Override
  public void onClick(View v){
    Toast.makeText(this,"Hello World",Toast.LENGTH_LONG).show()
  }
}

在kotlin我们可以通过传递一个lambda表达式去代替这个实例

btn_test.setOnClickListener { view : View ->
      Toast.makeText(this,"Hello World",Toast.LENGTH_LONG).show()
}

可以以这种方式去实现的原因是OnClickListener接口只有一个抽象方法,这种接口在kotlin中被当作函数式接口,或者SAM接口,SAM代表单抽象方法,类似的还有像Runnable和Callable这样的函数式接口.

把lambda当作参数传递给Java方法

我们在java中定义一个

void postponeComputation(int delay,Runnable computation){
}

然后使用lambda表达式去传递Runnable这个参数

postponeComputation(1000){
    print("hello world")
}

注意这个lambda实参编译器会自动把它转换成一个Runnable实例. 这种调用方式效果和显示的实现一个Runnable匿名对象一样

postponeComputation(1000,object : Runnable{
    override fun run(){
        println(42)
    }
})

但实际不一样的是,每次调用这种语句会重复创建Runnable对象,而使用lambda表达式作为实参如果没有访问任何来自定义它的函数变量那么只会创建一个对象.

如果想要完全等价需要这样去定义

val runnable = Runaable{ println(42) }
fun handleComputation(){
   postponeComputation(1000,runnable)
}

另外如果从包围它的作用域中捕捉了变量,每次调用就不会重用同一个实例了, 如下调用每次都会使用一个新的Runnable实例.

fun handleComputation(id : String){
   postponeComputation(1000){println(id)}
}

实际上从kotlin1.0起, 每个lambda都会被编译成一个匿名类,如果lambda捕捉了变量,每个被捕捉的变量会在匿名类中有对应的字段.

SAM构造方法:显式地把lambda转换成函数式接口.

在有的方法中需要返回一个函数式接口,不能返回一个lambda, 可以用SAM构造方法把它包装起来. 如下

fun createAllDoneRunable() : Runnable{
  return Runnable{ println(“All done”) }
}

SAM函数名称和底层函数式接口的名称一样. SAM构造方法只接收一个参数-一个被用作函数式接口单抽象方法体的lambda,并返回一个接口类的实例.

另外除了返回值通过lambda创建函数式接口外,也可以把lambda生成的函数式接口放在一个变量中,如下

val listener = OnClickListener{
  view -> val text = when(view.id){
    R.id.button1 -> “First button”
    R.id.button2 -> “Second button”
    else -> “Unknown button"
  }
  toast(text)
}
button1.setOnClickListener(listener)
button2.setOnClickListener(listener)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

您可能感兴趣的文章:

相关文章

  • Ubutu1604安装colmap实现方法详细教程

    Ubutu1604安装colmap实现方法详细教程

    这篇文章主要介绍了Ubutu1604安装colmap实现方法详细教程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • Android Hilt依赖注入的使用讲解

    Android Hilt依赖注入的使用讲解

    这篇文章主要介绍了Android Hilt依赖注入的使用,首先,某个类的成员变量称为依赖,如若此变量想要实例化引用其类的方法,可以通过构造函数传参或者通过某个方法获取对象,此等通过外部方法获取对象实例的称为依赖注入
    2023-01-01
  • Android 使用地图时的权限请求方法

    Android 使用地图时的权限请求方法

    今天小编就为大家分享一篇Android 使用地图时的权限请求方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • Android实现EditText图文混合插入上传功能

    Android实现EditText图文混合插入上传功能

    这篇文章主要为大家详细介绍了Android实现EditText图文混合插入上传功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • Android操作系统的架构设计分析

    Android操作系统的架构设计分析

    这篇文章主要介绍了Android操作系统的架构设计分析,Android系统架构分为Linux内核驱动、C/C ++框架、Java框架、Java应用程序,本文分别讲解了它的作用,需要的朋友可以参考下
    2015-06-06
  • android利用xml实现分割线

    android利用xml实现分割线

    这篇文章主要介绍了android利用xml实现分割线的方法,如何用xml产生一个分割线?感兴趣的小伙伴们可以参考一下
    2015-12-12
  • android 触屏的震动响应接口调用方法

    android 触屏的震动响应接口调用方法

    android 相关开发过程中,经常会使用到触屏的震动响应接口,为此本文列出以下方法,想要了解的朋友可以参考下
    2012-11-11
  • Android 下的 QuickJS Binding 库特性使用详解

    Android 下的 QuickJS Binding 库特性使用详解

    这篇文章主要介绍了Android 下的 QuickJS Binding 库特性使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • Android 通过API获取数据库中的图片文件方式

    Android 通过API获取数据库中的图片文件方式

    这篇文章主要介绍了Android 通过API获取数据库中的图片文件方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • 详解Android使用Socket对大文件进行加密传输

    详解Android使用Socket对大文件进行加密传输

    这篇文章主要介绍了详解Android使用Socket对大文件进行加密传输,使用Socket进行文件传输过程时,需要先进行加密,有兴趣的可以了解一下。
    2017-01-01

最新评论