扩展(Extension),可以说是 Kotlin 里最有意思的特性,没有之一。
本文会系统的讲解 Kotlin 扩展函数 和 扩展属性 以及比较难懂的 扩展作用域 和 扩展静态解析 。
Kotlin 的扩展,用起来就像是: 能给一个类新增功能 这个新增的功能,可以是函数 ,也可以是 属性 。
借助 Kotlin 扩展,我们能轻易的写出这样的代码:
// 扩展函数
"KotlinJetpackInAction".log()
// 扩展属性
val isBlank = String.isNullOrBlank
以上的代码,看起来就像是我们修改了原本 String 并且往里面加了方法和属性: log() , isNullOrBlank 。
初次见到 扩展 这个特性的时候,我真的被惊艳到了。虽然 扩展 不是 Kotlin 独有的特性(别的现代语言也有),但
是,Kotlin 能在兼容 Java 的同时引入这样的特性,那就真的很了不起了。
顶层扩展,是最常用的扩展方式,它的定义方式也很简单,以上面的两行代码为例,我们看看它们分别应该怎么定义吧。
// BaseExt.kt
package com.boycoder.kotlinjetpackinaction
// 注意!!
// 顶层扩展不能定义在任何 Class 里,不然它就变成“类内扩展”了!
// 为 String 定义扩展函数
fun String.log() {
println(this)
}
// 为 String 定义扩展属性
val String?.isNullOrBlank: Boolean
get() = this == null || this.isBlank()
Package级别的顶层扩展理解起来很简单,类内扩展 会稍微复杂些。
类内扩展 (Declaring extensions as members) 在官方中文站的翻译是: 扩展声明为成员 ,这个翻译虽然更接近本质,但太僵硬了,因此我在这里用类内扩展指代它。
类内扩展的写法跟顶层扩展是一模一样的,区别在于它 在其他类的里面 。让我们来看一个例子:
// 被扩展的类
class Host(val hostname: String) {
fun printHostname() { print(hostname) }
}
class Test(val host: Host, val port: Int) {
fun printPort() { print(port) }
// 在 Test 类内给 Host 增加了一个扩展函数
fun Host.printConnectionString() {
printHostname() // Host.printHostname()
print(":")
printPort() // Test.printPort()
}
// 在 Test 类内给 Host 增加了一个扩展属性
val Host.isHomeEmpty: Boolean
get() = hostname.isEmpty()
fun test() {
host.printConnectionString()
}
}
fun main() {
// 报错,Host 的类内扩展,在外面无法访问,这是与顶层扩展的不同
Host("").isHomeEmpty
Host("").printConnectionString()
}
想要学习Kotlin,多一个大厂面试机会的朋友们,这里有一份《高级Kotlin强化实战》,能更快更好的帮助你从入门到精通Kotlin!扫码100%免费领取~
##第三章 项目实战《Kotlin Jetpack 实战》