?在Kotlin中乖篷,為什么會(huì)有擴(kuò)展乘粒?因?yàn)榭梢宰屖褂谜撸ɑ蚨x者)不修改即有源代碼的情況下幢妄,同時(shí)又不借助于裝飾模式等任何一種設(shè)計(jì)模式的情況下着裹, 以一種比較快捷和方便的方式去為一個(gè)即有的類增加功能赶熟,而提供的這樣的一種手段瑰妄。Kotlin通過(guò)擴(kuò)展可以很好的解決Java中充斥的各種輔助類問(wèn)題。
- 擴(kuò)展函數(shù)(方法)
如下所示映砖,是一個(gè)擴(kuò)展函數(shù)的例子:
/**
* 擴(kuò)展性间坐,extension
* 在不改變?cè)蓄惤Y(jié)構(gòu)的情況下,給這個(gè)類動(dòng)態(tài)的增加一些額外的功能
*/
class ExtensionTest {
fun add(a: Int, b: Int) = a + b
fun sub(a: Int, b: Int) = a - b
}
/**
* ExtensionTest類的擴(kuò)展方法
*/
fun ExtensionTest.mul(a: Int, b: Int) = a * b
fun main(args: Array<String>) {
var extensionTest = ExtensionTest();
println(extensionTest.add(1, 3))
println(extensionTest.sub(2, 2))
println(extensionTest.mul(3, 1))
}
輸出結(jié)果:
4
0
3
- 擴(kuò)展本身并不會(huì)真正的修改目標(biāo)類,也就是說(shuō)它并不會(huì)在目錄類中插入新的屬性或方法竹宋;
- 擴(kuò)展函數(shù)的解析是靜態(tài)分發(fā)的劳澄,而不是動(dòng)態(tài)的,即不支持多態(tài)蜈七,調(diào)用只取決于對(duì)象的聲明類型秒拔;
- 調(diào)用是由對(duì)象的聲明類型所決定的,而不是由對(duì)象的實(shí)際類型決定飒硅。
如下所示:
open class ClassA
class ClassB: ClassA()
fun ClassA.a() = "a"
fun ClassB.a() = "b"
fun myPrint(a: ClassA) {
println(a.a())
}
fun main(args: Array<String>) {
myPrint(ClassA())
}
輸出結(jié)果:
a
// 由ClassA改為ClassB砂缩,輸出結(jié)果也是a
fun main(args: Array<String>) {
myPrint(ClassB())
}
輸出結(jié)果:
a
如果一個(gè)類有了某一個(gè)方法,然后對(duì)這個(gè)類進(jìn)行擴(kuò)展三娩,擴(kuò)展的方法名及簽名都完全一樣庵芭,類里面即有的方法優(yōu)先級(jí)最高。注:不過(guò)實(shí)際情況不會(huì)出現(xiàn)雀监,不會(huì)對(duì)類擴(kuò)展一個(gè)跟類里包含的方法一樣的方法双吆。如下所示:
class ClassC {
fun foo() {
println("cc.foo")
}
}
fun ClassC.foo() {
println("cc.foo2")
}
fun main(args: Array<String>) {
ClassC().foo()
}
輸出結(jié)果:
cc.foo
- 擴(kuò)展屬性
如下所示,是一個(gè)擴(kuò)展屬性的例子:
class ExtensionProperty
val ExtensionProperty.name: String
get() = "hello"
fun main(args: Array<String>) {
var extensionProperty = ExtensionProperty()
println(extensionProperty.name)
}
輸出結(jié)果:
hello
- 伴生對(duì)象擴(kuò)展
如下所示会前,是一個(gè)伴生對(duì)象擴(kuò)展的例子:
class CompanionExtension {
companion object MyObject {
}
}
fun CompanionExtension.MyObject.method() {
println("hello world!")
}
fun main(args: Array<String>) {
CompanionExtension.method()
}
輸出結(jié)果:
hello world!
- 擴(kuò)展的作用域
- 擴(kuò)展函數(shù)所定義在的類實(shí)例叫做分發(fā)接收者(dispatch receiver)好乐;
- 擴(kuò)展函數(shù)所擴(kuò)展的那個(gè)類的實(shí)例叫做擴(kuò)展接收者(extension receiver);
- 當(dāng)以上兩個(gè)名字出現(xiàn)沖突時(shí)瓦宜,擴(kuò)展接收者的優(yōu)先級(jí)最高蔚万。
如下所示:
class Demo {
fun method() {
println("demo method")
}
}
class Demo2() {
fun method2() {
}
fun Demo.hello() {
method()
method2()
}
fun world(demo: Demo) {
demo.hello()
}
fun Demo.output() {
println(toString())
println(this@Demo2.toString())
}
fun test() {
var demo = Demo()
demo.output()
}
}
fun main(args: Array<String>) {
Demo2().test()
}
輸出結(jié)果:
com.ssy.kotlin.demo.Demo@6e0be858
com.ssy.kotlin.demo.Demo2@61bbe9ba
注:this@Demo2,Kotlin提供的特殊語(yǔ)法歉提,是為了解決函數(shù)(方法)重名的問(wèn)題笛坦,this@分發(fā)接收者的名字墓陈。