Kotlin基础教程-扩展

来源:互联网 发布:快牙软件下载 编辑:程序博客网 时间:2024/06/05 18:59

扩展

有这样一个场景,当基础jar包中的一些类的方法不满足我们的要求,我们就需要重写或者添加新的方法,这个时候就需要扩展以后类的功能。
Kotlin提供了一种非常简单可以扩展已有类的函数和属性的方式。

函数扩展

fun MutableList<Int>.swap(x: Int, y: Int) {    val temp = this[x] // this 对应 list    this[x] = this[y]    this[y] = temp}fun main(args: Array<String>) {    val list = mutableListOf<Int>(1,2,3,5)    list.swap(1,3)    list.forEach{        println("${it} ")    }}

MutableList类扩展了个函数swap,以后MutableList对象就可以使用该函数。

注意

扩展并没有修改被扩展的类,只是该类的实例对象可以通过.来访问该扩展函数或者属性。

静态分发与动态分发

概念

动态分发是实现多态的基本原理,而扩展是使用静态分发的,既定义时使用什么类,实际运行也就是该对象,而不是根据运行时的状态改变。

open class CCclass DD : CC()fun CC.foo() = "c"fun DD.foo() = "d"fun printFoo(c: CC) {    println(c.foo())}fun main(args: Array<String>) {    printFoo(DD())}

上面代码经过传入的是DD对象,但是实际运行的还是CC.foo()函数:

这里写图片描述

成员函数VS扩展函数

如果扩展函数已经存在,那么调用的时候肯定会使用成员函数,除非该函数名称相当,但是参数不一样,既是重载函数:

同名函数

class Doctorq {    fun foo() {        println("member")    }}fun Doctorq.foo() {    println("extension")}fun main(args: Array<String>) {    val doctorq = Doctorq()    doctorq.foo()}

输出结果是member

重载函数

class Doctorq {    fun foo() {        println("member")    }}fun Doctorq.foo(i: Int) {    println("extension")}fun main(args: Array<String>) {    val doctorq = Doctorq()    doctorq.foo(1)}

输出结果是extension

接受者为null

fun Any?.toString(): String {    if (this == null) return "null"    // 在空检查之后,`this` 被自动转为非空类型,因此 toString() 可以被解析到任何类的成员函数中    return toString()}fun main(args: Array<String>) {    val doctorq = null    doctorq.toString()}

为任何对象添加toString函数,包括null

这里写图片描述

属性扩展

val <T> List<T>.lastIndex:  Int    get() = size-1fun main(args: Array<String>) {    val doctorq = listOf<Int>(2,4,4,5)    doctorq.lastIndex}
原创粉丝点击