在kotlin中,可以自由扩展任何类的方法和属性。在不修改原类的情况下,kotlin能给一个类扩展新功能而无需继承该类。java没有该特性。

一、扩展函数
1、给String类扩展两个函数
注意:扩展函数不能卸载类中。

package com.htkj.flowtest.test

fun String.firstChar() : String {
    if (this.length == 0) {
        return ""
    }
    return this[0].toString()
}

fun String.endChar() : String {
    if (this.length == 0) {
        return ""
    }
    return this[this.length -1].toString()
}

在其他package路径下,需要import导入扩展函数。

package com.htkj.flowtest               // 与扩展函数不在同一个包路径下

import com.htkj.flowtest.test.firstChar // 导入扩展函数 firstChar 
import com.htkj.flowtest.test.endChar   // 导入扩展函数 endChar   

//  扩展函数
println("Extendedfunction : bdfhdbdbd first char is ${"bdfhdbdbd".firstChar()},the last char is ${"bdfhdbdbd".endChar()}")

输出:I/System.out: Extendedfunction : bdfhdbdbd first char is b,the last char is d

2、给List类扩展一个过滤函数
使用Kotlin中的扩展函数为List扩展一个filter()函数

// kotlin中给List扩展一个filter函数
// <T> 表示泛型
// this 指向调用者对象
fun <T> List<T>.myfilter(predicate : (T) ->Boolean) : MutableList<T> {
    val result = ArrayList<T>()
    this.forEach {
        if (predicate(it)) {       // 如果满足谓词判断条件
            result.add(it)
        }
    }
    return result
}

// 调用
val list1 = mutableListOf(6,4,83,937,8764,3,9)
val result = list1.myfilter { it % 2 == 1 }
println("Extendedfunction : result = ${result}")

// 输出
I/System.out: Extendedfunction : result = [83, 937, 3, 9]

二、扩展属性
除了扩展一个类的函数,还可以扩展类属性。例如,给MutableList扩展两个属性:firstElement,lastElement

var <T> MutableList<T>.firstElement : T     // 扩展属性
get () {                                    // 扩展属性 firstElement 的get()函数
    return this[0]
}
set (value) {                              // 扩展属性 firstElement 的set()函数
    this[0] = value
}

var <T> MutableList<T>.lastElement : T
get() {
    return this[this.size - 1]
}

set(value) {
    this[this.size - 1] = value
}

// 调用
val list1 = mutableListOf(6,4,83,937,8764,3,9)
println("ExtendedAttribute : thie first element is ${list1.firstElement},the last element is ${list1.lastElement}")
list1.firstElement = 786543
println("ExtendedAttribute : thie first element is ${list1.firstElement}")

// 输出
I/System.out: ExtendedAttribute : thie first element is 6,the last element is 9
I/System.out: ExtendedAttribute : thie first element is 786543

扩展属性允许定义在类或者Kotlin文件中,不允许定义在函数中。

三、扩展的实现原理
参考《Kotlin从入门到进阶实战》90页

四、扩展中的this关键字
在前面的List扩展函数myfilter()的实现中,用到了一个this关键字。 这里的this指的是接受者对象(receiver object),也就是调用扩展函数时,在点号“.”之前指定的对象实例。为了表示当前函数的接收者(receiver),kotlin中使用this表达式:
1) 在类的成员函数中,this指向这个类的当前对象实例;
2) 在扩展函数中,或带接收者的函数字面值(function literal)中,this代表调用函数时,在点号左侧传递的接收者参数;
3) 如果this 没有限定符,那么它指向包含当前代码的最内层范围,如果想要指向其他范围内的this,需要使用标签限定符。

编程技巧提示: 可以新建一个公共源文件,把自定义的扩展属性和扩展函数都放到包中,作为一个通用工具类来使用

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐