问题汇总:
1、什么是扩展?
Kotlin提供一种给类增加新功能的能力,却不需要继承或者采用设计模式(装饰者模式)。Kotlin支持扩展函数
extension functions
和扩展属性extension properties
。
2、简单扩展实例:
MutableList是接收者,swap是函数扩展。
fun MutableList<Int>.swap(index1: Int, index2: Int) {
val tmp = this[index1] // 'this'对应List
this[index1] = this[index2]
this[index2] = tmp
}
val l = mutableListOf(1, 2, 3)
l.swap(0, 2) //给MutableList扩展了`swap`功能
3、扩展是静态完成的,类型是由调用的函数静态决定的
open class C
class D: C()
fun C.foo() = "c"
fun D.foo() = "d"
fun printFoo(c: C) {
println(c.foo()) //决定了参数类型是C,会调用C.foo()
}
printFoo(D()) //会调用C.foo()
4、类的成员函数名与类的扩展函数冲突:
- 成员函数名与扩展函数名相同,使用时会调用成员函数。
- 可以使用不同参数进行函数重载,就可以通过不同参数调用两种函数。
5、“可为空”的接收者
扩展的接收者可以为空,但是需要确定
是否为空
。下面的toString()扩展就解释了为何toString()不需要判断空
fun Any?.toString(): String {
if (this == null) return "null"
// 非空判断后,下面会进行转换,转换为String
// ...
return toString()
}
6、扩展属性的特点:
- 扩展属性并不是真的在类中插入成员,因此没有有效的方法使得扩展属性拥有
backing field
。- 因此扩展属性不允许有扩展属性。
- 扩展属性的行为只能通过显式的getter和setter定义
7、可以扩展同伴对象的属性和函数。
同伴对象扩展和一般的同伴对象成员一样,可以直接通过ClassName.fun()来调用
8、扩展范围
- 一般是直接在最顶层(直接在包下面)定义扩展
- 在声明包之外使用扩展,需要import该包或者具体的扩展。
9、将扩展作为成员
声明扩展的类的实例称为调度接收方,扩展方法的接收方类型的实例称为扩展接收方。