歡迎關(guān)注 二師兄Kotlin
轉(zhuǎn)載請注明出處 二師兄kotlin
友元對象擴展
如果一個類中定義了一個友元對象(companion object
)拍柒,你就可以對這個友元對象進(jìn)行函數(shù)和屬性擴展碧绞。
class MyClass {
companion object { } // will be called "Companion"
}
fun MyClass.Companion.foo() {
// ...
}
正如友元對象的常規(guī)函數(shù)一樣伟端,只能使用所在類的類名作為前綴進(jìn)行調(diào)用:
MyClass.foo()
擴展之作用域
很多情況下我們都在頂級包下進(jìn)行擴展
package foo.bar
fun Baz.goo() { ... }
如果需要在超出包的范圍內(nèi)進(jìn)行使用的話,需要進(jìn)行導(dǎo)入(import):
package com.example.usage
import foo.bar.goo // importing all extensions by name "goo"
// or
import foo.bar.* // importing everything from "foo.bar"
fun usage(baz: Baz) {
baz.goo()
)
聲明擴展作為成員函數(shù)
在一個類的內(nèi)部蜓陌,你可以為另外一個類聲明擴展。而在擴展內(nèi)部,則存在多個隱式的接收者---對象可以訪問成員而不需顯示指定歸屬類名匾七。在聲明擴展所在的類實例叫做分發(fā)接收者(dispatch receiver
),而擴展函數(shù)的接收者類的實例叫做擴展接收者( extension receiver
)江兢。
class D {
fun bar() { ... }
}
class C {
fun baz() { ... }
fun D.foo() {
bar() // calls D.bar
baz() // calls C.baz
}
fun caller(d: D) {
d.foo() // call the extension function
}
}
萬一 分發(fā)接收者和擴展接收者的函數(shù)名存在沖突昨忆,優(yōu)先使用擴展接收者的函數(shù)。如果要引用分發(fā)接收者(dispatch receiver)的成員杉允,請使用qualified this
syntax邑贴。
class C {
fun D.foo() {
toString() // calls D.toString()
this@C.toString() // calls C.toString()
}
將擴展函數(shù)聲明時,可以使用open
來聲明叔磷, 并且可以在子類中重寫拢驾。這就意味著擴展函數(shù)對于分發(fā)接收者來說是虛函數(shù),而對于擴展接收者來說是靜態(tài)的改基。
open class D {
}
class D1 : D() {
}
open class C {
open fun D.foo() {
println("D.foo in C")
}
open fun D1.foo() {
println("D1.foo in C")
}
fun caller(d: D) {
d.foo() // call the extension function
}
}
class C1 : C() {
override fun D.foo() {
println("D.foo in C1")
}
override fun D1.foo() {
println("D1.foo in C1")
}
}
C().caller(D()) // prints "D.foo in C"
C1().caller(D()) // prints "D.foo in C1" - dispatch receiver is resolved virtually
C().caller(D1()) // prints "D.foo in C" - extension receiver is resolved statically
動機
在Java中繁疤,我們習(xí)慣于使用類名為*Utils
:FileUtils
, StringUtils
等等。著名的java.util.Collections
也屬于這一類寥裂。但是這些類有一些用起來讓人覺得很不爽的地方:
// Java
Collections.swap(list, Collections.binarySearch(list, Collections.max(otherList)),
Collections.max(list))
或者我們可以靜態(tài)導(dǎo)入嵌洼,變成這樣寫:
// Java
swap(list, binarySearch(list, max(otherList)), max(list))
雖然這樣寫會稍微好一些,但是我們卻無法從IDE的強大的代碼補全功能中獲得幫助封恰。如果我們可以這樣寫會不會更好一些呢:
// Java
list.swap(list.binarySearch(otherList.max()), list.max())
但是我們總不能實現(xiàn)List
的所有函數(shù)吧麻养,這個時候Kotlin的擴展功能就可以對我們產(chǎn)生幫助了。
本節(jié)完