Kotlin基础十二拓展方法和属性
Kotlin基础十二
拓展方法和属性
在Kotlin中,有一个很神奇的特性,就是可以为已经存在的类添加方法和属性。具体实现也很简单:
fun String.lastChar(): Char = this.get(this.length - 1)
fun main(args: Array<String>) {
println("Hello, Kotlin".lastChar())
}
//result:
n
Process finished with exit code 0
String
类原本并没有lastChar()
方法,但我们可以像上面这样拓展了String
类,为其拓展了这个方法,我们就可以像使用String
类的其他方法一样使用我们拓展的方法。
我们看这个方法是怎样声明的:
fun String.lastChar(): Char = this.get(this.length - 1)
要拓展的类,在这里也就是String
,被称为receiver type
,this
就是receiver object
,这和声明一个函数几乎没什么差别,先是fun
关键字,然后是要拓展的类的类型,紧接着是.
加方法名,再声明返回值,receiver object
(可以省略this
),其他的和函数的声明没什么太大的差别。
需要注意的是,拓展方法无法访问类的private
和protected
成员。
导入extension function
import Kt03.lastChar
fun main(args: Array<String>) {
println("import extension function".lastChar())
}
拓展方法不会自动导入,需自己动手。导入拓展的方法也很简单,就是import packageName.extensionFunction
.
如果使用import packageName.*
,将会导入这个包里面的全部函数、类和拓展方法。
你还可以用as
关键字来命名别名,就像python那样:import packageName.extensionFunction as ef
.
import Kt03.lastChar as last
拓展方法具有静态属性,这意味着不能在子类中覆写父类的拓展方法。
从Java调用Kotlin的拓展方法
Kotlin的拓展方法转成Java时会被编译成Java的静态方法,因此调用Kotlin的拓展方法在Java中就像调用静态方法那样简单:
import Kt03.Kt35Kt;
public class CallExtensionFunc {
public static void main(String...agrs) {
System.out.println(Kt35Kt.lastChar("Java"));
}
}
//result:
a
Process finished with exit code 0
拓展属性
拓展属性和拓展方法几乎没什么差别:
fun String.lastChar(): Char = get(length - 1)
val String.lastChar: Char get() = get(length-1)
fun main(args: Array<String>) {
println("Hello, Kotlin".lastChar())
println("Hello, world".lastChar)
} //result:
n
d
Process finished with exit code 0
需要注意的是get()
是必须被声明和定义的。因为在拓展属性中,编译器不会再帮你自动生成getter
和setter
了。
在Kotlin中,之所以kotlin的集合比Java的集合多了更多的操作,就是因为Kotlin有拓展方法这个特性,像Kotlin集合中的last
、max
这些方法就是拓展方法。