详解如何实现一个Kotlin函数类型

目录
  • 接口与函数类型
  • 总结

接口与函数类型

业务开发中,经常会有实现一个函数式接口(即接口只有一个方法需要实现)的场景,大家应该都会不假思索的写出如下代码:

interface Callback {
    fun response(): String
}

class Achieve: Callback {

    override fun response(): String {
        return ""
    }
}

这么写当然没什么毛病,甚至为了让kotlin支持对接口CallbackSAM转换,你还可以在接口前面增加一个fun修饰:

fun interface Callback {
    fun response()
}

但是对于Kotlin而言,本身函数类型是可以被实现的,也就是说我们可以使用函数类型替换函数式接口,让子类去实现,代码如下:

class Achieve: () -> String {
    override fun invoke(): String {
        return ""
    }
}

这种实现函数类型的类需要重写的方法都是invoke(),方法返回值类型对应的就是函数类型的返回值类型。

这种写法我在LeakCanary的源码中就看到了应用,比如监听Fragment是否销毁的类AndroidOFragmentDestroyWatcher

在这里写下我对这两种方式优缺点的比较:

1.函数类型相比较于接口去实现的优点如下:

参数类型更加直观

某个类实现了函数类型,能直观的看到这个函数类型需要传入的参数有哪些,是什么类型,返回值又是什么类型,而如果实现了一个接口,一般大家都习惯跳转到接口定义的地方看接口方法的实现,所以这一点函数类型会更加方便些

检索更方便

函数类型需要重写的方法名一定叫invoke,所以如果我需要看下某个实现类对重写方法的具体实现逻辑,直接在当前类中搜索invoke关键字定位到这个方法即可;而如果是一个接口接口,我得跳转到接口的定义的地方看接口方法名是什么,才能去实现类中去搜索,所以在这点上函数类型会更加方便些

2.函数类型相比较于接口去实现的缺点如下:

函数类型语义性会比较差:

毕竟定义的接口名一般是和业务进行绑定的,能大概知道这个接口是干啥用的,更加清晰直观,当然这个问题我们可以使用typealias解决,但就会失去上面参数类型更加直观的优点

多态性会比较差(自己编的,不知道合不合理)

比如如果定义的一个接口去实现,我们很容易实现下面这种功能:

fun test(achieve: Achieve) {
    if (achieve is Callback) {
        //实现某些逻辑
    }
}

而如果使用函数类型去实现这种逻辑:

看起来是不是很奇怪,而且对于很多需要重写的方法签名都是相同的(方法参数和返回值都是相同的),根本无法实现这种功能,具体的看下面一点的描述。

无法实现多个相同的函数类型

业务场景中也存在实现多个接口,并且接口定义的方法参数和返回值类型都是相同的,比如下面:

fun interface Callback {
    fun response(): String
}

fun interface Callback2 {
    fun response2(): String
}

class Achieve2: Callback, Callback2 {
    override fun response(): String {
        return ""
    }

    override fun response2(): String {
        return ""
    }
}

如果使用函数类型根本无法实现上面的这种多个接口实现的功能:

直接进行报错。

总结

不管是实现函数类型还是接口,两者都各有其优缺点,大家需要根据业务场景进行具体的选择

到此这篇关于详解如何实现一个Kotlin函数类型的文章就介绍到这了,更多相关Kotlin函数类型内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • kotlin快速入门之标准函数与静态方法

    目录 标准函数 with run apply 静态方法 单例类实现静态方法 伴生类实现静态方法 注解实现静态方法 顶层方法实现静态方法 总结 标准函数 首先我们介绍标准函数 with.run.apply,如果你了解javascript,那理解kotlin的标准函数width.run.apply那简直不要太轻松.with.run.apply与javascript中的with的意义基本一模一样,只是含有一些细微差别. with with它接收两个参数,第一个参数可以是任意类型的对象,第二个参数是一个

  • Kotlin挂起函数原理示例剖析

    目录 一.序言 二.CPS原理 CPS参数变化 CPS返回值变化 三.挂起函数的反编译 四.伪挂起函数 五.多个挂起函数前后关联 六.在Java中调用suspend函数 七.总结 一.序言 Kotlin挂起函数平时在学习和工作中用的比较多,掌握其原理还是很有必要的.本文将一步一步带着大家分析其原理实现. ps: 文中所用的Kotlin版本是1.7.0. 二.CPS原理 在某个Kotlin函数的前面加个suspend函数,它就成了挂起函数(虽然内部不一定会挂起,内部不挂起的称为伪挂起函数). 先随

  • Kotlin函数使用示例教程

    目录 我们先看看简单的函数 我们写一个求和函数 函数头 函数体 调用函数非常简单 反编译Java源代码步骤 接下来我们来看看匿名函数 这是接口的声明 我们先看看简单的函数 // 前面的文章我们了解到它是入口函数 fun main() { } // 对应的Java 语言,熟悉的Java 的朋友会发现,哈哈,这就是一个Java静态方法 // 我们通过两种语言的对比,能够对函数有一个更好的理解 public static final void main() { } // 如果没有 Java 基础,不适

  • Kotlin匿名函数使用介绍

    目录 1.函数的声明 2.函数参数 3.Unit函数 4.匿名函数 5.匿名函数的参数 6.lambda表达式 7.定义参数 8.匿名函数 9.函数的引用 10.函数类型作为返回类型 1.函数的声明 kotlin中函数的声明和java中有所不同. 1)得有fun关键字修饰, 2)参数的声明方式和变量声明类似 age:Int,先写参数名,后面跟着参数类型 3)  返回值类型写在参数的后面. //可见性修饰符 函数关键字 方法法名 参数名 参数类型 返回值 private fun functionN

  • 详解如何实现一个Kotlin函数类型

    目录 接口与函数类型 总结 接口与函数类型 业务开发中,经常会有实现一个函数式接口(即接口只有一个方法需要实现)的场景,大家应该都会不假思索的写出如下代码: interface Callback { fun response(): String } class Achieve: Callback { override fun response(): String { return "" } } 这么写当然没什么毛病,甚至为了让kotlin支持对接口Callback的SAM转换,你还可以

  • 详解JavaScript中常用的函数类型

    网页中的java代码需要写在JavaScript中,里面部分少不了函数,介绍一下JavaScript中常用的函数类型. 1.可变函数 <script> function show(){ alert("第一个..."); } function show(str){ alert("第二个"); } function show(a,b){ alert("第三个..."); alert(a+":"+b); } </s

  • jQuery position() 函数详解以及jQuery中position函数的应用

    position()函数用于返回当前匹配元素相对于其被定位的祖辈元素的偏移,也就是相对于被定位的祖辈元素的坐标.该函数只对可见元素有效. 所谓"被定位的元素",就是元素的CSS position属性值为absolute.relative或fixed(只要不是默认的static即可). 该函数返回一个坐标对象,该对象有一个left属性和top属性.属性值均为数字,它们都以像素(px)为单位. 与offset()不同的是:position()返回的是相对于被定位的祖辈元素的坐标,offse

  • 详解Python3中的 input() 函数

    一.知识介绍: 1.input() 函数,接收任意输入,将所有输入默认为字符串处理,并返回字符串类型: 2.可以用作文本输入,如用户名,密码框的值输入: 3.语法:input("提示信息:") . 二.运用演示: 1.接收任意输入,并返回字符串类型: >>>height = input("输入身高:")          #运行 输入身高: 170                      #输入整数170 >>> type(a)

  • 详解pandas.DataFrame.plot() 画图函数

    首先看官网的DataFrame.plot( )函数 DataFrame.plot(x=None, y=None, kind='line', ax=None, subplots=False, sharex=None, sharey=False, layout=None,figsize=None, use_index=True, title=None, grid=None, legend=True, style=None, logx=False, logy=False, loglog=False,

  • 详解Go语言Slice作为函数参数的使用

    目录 前言 问题与解析 典型问题 其它疑问1 其它疑问2 结论 参考链接 前言 首先要明确Go语言中实质只有值传递,引用传递和指针传递是相对于参数类型来说. 个人认为上诉的结论不对,把引用类型看做对指针的封装,一般封装为结构体,结构体是值类型,所以感觉都是值传递.不然我感觉其它语言实质不也都是值传递?不过我刚学Go,可能还没完全弄懂,这个有问题可以互相讨论下. Go语言中的值类型:int.float.bool.array.sturct等,声明一个值类型变量时,编译器会在栈中分配一个空间,空间里存

  • 详解Anyscript开发指南绕过typescript类型检查

    目录 前言 场景设定 解决方法 注释忽略 场景用例 类型断言 场景用例 泛型转换 场景用例 总结 前言 随着越来越多的前端项目采用 typescript 来开发,越来越多前端开发者会接触.使用这门语言.它是前端项目工程化的一个重要帮手,结合 vscode 编辑器,给予了前端开发者更严谨.高效的编码体验.但同时,严格的类型检查也会使部分开发者的编码效率有所降低,将时间花费在解决类型冲突.类型不匹配上,从而导致望而却步,迟迟不敢上手. 本文描述了几种绕过 typescript 类型检查的方法,帮助t

  • 详解MySQL中数据类型和字段类型

    目录 1. mysql的数据类型 (1)数值型 (2)字符(串)型 (3)日期和时间型 (4)null值 2. mysql的列(字段)类型 2.1数值列类型 2.2字符串列类型 2.3日期时间列类型 1. mysql的数据类型 在mysql中有如下几种数据类型: (1)数值型 数值是诸如32 或153.4 这样的值.mysql 支持科学表示法,科学表示法由整数或浮点数后跟“e”或“e”.一个符号(“+”或“-”)和一个整数指数来表示.1.24e+12 和23.47e-1 都是合法的科学表示法表示

  • 详解C语言用malloc函数申请二维动态数组的实例

    详解C语言用malloc函数申请二维动态数组的实例 C语言在程序运行中动态的申请及释放内存十分方便,一维数组的申请及释放比较简单. Sample one #include <stdio.h> int main() { char * p=(char *)malloc(sizeof(char)*5);//申请包含5个字符型的数组 free(p); return 0; } 是否申请二维动态内存也如此简单呢?答案是否定的.申请二维数组有一下几种方法 Sample two /* 申请一个5行3列的字符型

  • 详解python statistics模块及函数用法

    本节介绍 Python 中的另一个常用模块 -- statistics模块,该模块提供了用于计算数字数据的数理统计量的函数.它包含了很多函数,具体如下表: 名称 描述 mean() 数据的算术平均数("平均数") harmonic_mean() 数据的调和均值 median() 数据的中位数(中间值) median_low() 数据的低中位数 median_high() 数据的高中位数 median_grouped() 分组数据的中位数,即第50个百分点 mode() 离散的或标称的数

随机推荐