Kotlin - 扩展函数 扩展属性

本文介绍了Kotlin的扩展函数和扩展属性。扩展函数和属性编译后成方法,首个参数是扩展接收者。扩展函数可在不修改源文件时为类扩展功能,有多种定义方式,如为超类、泛型、可空类型定义,且有调用和访问限制。扩展属性无状态,需自定义getter和setter。

扩展函数和扩展属性都会被编译成一个方法,这个方法的第一个参数就是扩展的接收者,然后才是其它各个参数。对于扩展属性来说 ,因为编译后这个属性并不存在,所以不能像一般的类属性那样对它进行初始化,而是要自定义 getter 和 setter 来访问它。

一、扩展函数

不修改源文件的情况下,为一个类扩展新功能无需继承重写,反编译成java是生成了对应的静态方法,并没有真正的修改了类。一个类只定义框架,工具函数可以通过外部扩展一点点地添加,尽量不改动原有的类。

  • fun 类名.方法名(参数列表) : 返回值类型 { 方法体 }
  • 扩展函数不允许打破封装,无法访问类中 private 和 protected 成员。
  • 扩展函数无法被覆盖,子父类都添加了同样的函数,子类执行自己的。
  • 一个类的扩展函数可以在同包目录下直接调用,出了这个范围需要导包使用。(不必像 Java 为了定义一个方法而专门创建工具类或使用装饰者模式,可以把公共函数写到一个 .kt 文件中,通过 import 导入就可以使用了)。
  • 写在成员函数位置上时所属于该类,写在顶层函数位置上时所属于该包。
  • 不要因为限制可见性将扩展函数定义为成员函数,而是使用可见性修饰符。private 修饰的顶层扩展函数只在该 kt 文件内可访问。
  • 建议向哪个类中添加扩展函数,就定义一个同名的文件(如StringExt.kt),这样便于你以后查找。当然也是可以定义在任何一个现有类当中的,并不一定非要创建新文件。通常来说,最好将它定义成顶层方法,这样可以让扩展函数拥有全局的访问域。

举例:为String类添加获取字符个数的扩展函数。

fun String.getCharCount() :Int{
    var count = 0
    for (it in this) {
        count++
    }
    return count
}
println("123456".getCharCount())    //打印:6

为超类定义扩展函数

为父类定义的扩展函数,所有子类都可以调用。

fun Any.printSelf() {
    println(this)
}

"hello".printSelf()
123.printSelf()

为泛型定义扩展函数

可以支持任何类型的接收者。一般用于链式调用,因此返回值类型为接收者类型。

fun <T> T.printSelf(): T {
    println(this)
    return this
}

"hello".printSelf().length
123.printSelf() + 1

为可空类型定义扩展函数

接收者可以为空,因此需要对 this == null 做判断。

//为可空类型定义的扩展函数
fun String?.printSelf1() {
    if(this == null) {
        return
    }
    println(this)
}

//为非空类型定义的扩展函数
fun String.printSelf2() {
    println(this)
}

fun main() {
    val str1: String = "123"
    val str2: String? = null
    str1.printSelf1()   //打印:123
    str1.printSelf2()   //打印:123
    str2.printSelf1()   //直接return掉了
    str2?.printSelf2()  //为null不会调用
}

二、扩展属性

尽管被叫做属性,但是不能拥有任何状态,不能添加额外的字段到现有的实例中。反编译成java一样是生成了对应的静态getter/setter

val String.lastChar: Char
    get() = get(length - 1)

var StringBuilder.lastChar: Char
    get() =  get(length - 1)
    set(value) {
        this.setCharAt(length -1, value)
    }

println("Kotlin".lastChar)
val sb = StringBuilder("Kotlin")
sb.lastChar = 'g'
println(sb)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值