Kotlin扩展(Extension)特性允许为现有的类添加新的函数和属性,而无需继承该类或使用装饰器模式。可以在不修改原始类的情况下,为它添加新的行为。
在实际编程当中是非常有用的功能,具体场景如:我们想修改JDK中的String,想在它的基础上增加一个方法"lastElement() "来获取末尾元素,如果使用Java,我们是无法通过常规手段实现的,因为我们无法修改JDK的源码。
扩展函数
fun ClassName.functionName(parameters) {
// 函数体
}
ClassName是要添加函数的类名,functionName是新函数的名称,parameters是函数的参数列表,函数体是函数的实际实现。
例如,我们可以向String类添加一个名为lastElement的扩展函数,用于来获取末尾元素:
fun String.lastElement(): Char? {
if (this.isEmpty()) {
return null
}
return this[length - 1]
}
// 使用扩展函数
fun main() {
val msg = "Hello Wolrd"
// lastElement就像String的成员方法一样可以直接调用
val last = msg.lastElement() // last = d
}
lastElement函数就会在所有String对象上可用,而不需要修改String类的源代码。
扩展函数实现原理,反编译示例代码:
public final class ExtKt {
public static final Character lastElement(String $this) {
CharSequence var1 = (CharSequence)$this;
if (var1.length() == 0) {
return null
}
return var1.charAt(var1.length() - 1);
}
}
public static final void main() {
String msg = "Hello Wolrd";
Character last = ExtKt.lastElement(msg);
}
原本定义在String类型上面的扩展函数lastElement(),变成了一个普通的静态方法。另外,之前定义的扩展函数lastElement()是没有参数的,但反编译后的Java代码中,lastElement(String $this)多了一个String类型的参数。原本msg.lastElement()的地方变成了ExtKt.lastElement(msg),这说明,Kotlin编写的扩展函数调用代码,最终会变成静态方法的调用。
扩展属性
Kotlin中的扩展属性允许我们向现有的类添加新的属性,而无需继承该类或使用装饰者模式。扩展属性的语法与扩展函数类似,但是在属性名之前需要指定接收者类型。
还是以lastElement为例,以扩展属性的方式实现:
// 接收者类型
val String.lastElement: Char?
get() = if (isEmpty()) {
null
} else {
get(length - 1)
}
fun main() {
val msg = "Hello Wolrd"
// lastElement就像String的成员属性一样可以直接调用
val last = msg.lastElement // last = d
}
需要注意的是,扩展属性并不会真正地向类中添加新的属性,它只是提供了一种便捷的方式来访问现有类的属性或计算新的属性值。不管是扩展函数还是扩展属性,它本质上都会变成一个静态的方法。
应用场景
Kotlin的扩展特性允许开发者向现有的类添加新的方法和属性,而无需继承该类或使用装饰者模式。
当然,扩展特性有一些使用限制:
Kotlin的扩展特性使用限制主要是为了保证代码的可靠性和可维护性。