頂層函數(shù)
創(chuàng)建一個名為 Join.kt 的文件:
package strings
fun joinToString(...): String { ... }
他會被編譯成以下 Java 代碼
package strings;
public class JoinKt {
public static String joinToString(...) { ... }
}
然后胳泉,在 Java 中可以按照如下方法使用它
import strings.JoinKt;
...
JoinKt.joinToString(list, ", ", "", "");
Kotlin 頂層函數(shù)相當(dāng)于 Java 中的靜態(tài)函數(shù)谈飒,往往我們在 Java 中會用到類似 Utils 的類來放置不屬于任何類的公共靜態(tài)函數(shù)卢未。
頂層屬性
const val UNIX_LINE_SEPARATOR = "\n"
這個等同于下面的 Java 代碼:
public static final String UNIX_LINE_SEPARATOR = "\n";
擴(kuò)展函數(shù)
理論上來說肪凛,擴(kuò)展函數(shù)非常簡單,它就是一個類的成員函數(shù)辽社,不過定義在類的外面伟墙。
package strings
fun String.lastChar(): Char = this.get(this.length - 1)
或者
package strings
fun String.lastChar(): Char = get(length - 1) //接收者對象成員可以不用this來訪問
對于你定義的一個擴(kuò)展函數(shù),它不會自動地在整個項目范圍內(nèi)生效滴铅,Kotlin允許你用和導(dǎo)入類一樣的語法來導(dǎo)入單個的函數(shù):
import strings.lastChar
val c = "Kotlin".lastChar()
在這個例子里面戳葵,String
就是接收者類型,而"Kotlin"
就是接收者對象汉匙。
從Java里面調(diào)用擴(kuò)展函數(shù)
實質(zhì)上拱烁,擴(kuò)展函數(shù)是靜態(tài)函數(shù),它把調(diào)用對象作為了它的第一個參數(shù)噩翠。假設(shè)它聲明在一個叫做StringUtil.kt的文件中:
/* Java */
char c = StringUtilKt.lastChar("Java");
不可重寫的擴(kuò)展函數(shù)
open class View {
open fun click() = println("View clicked")
}
class Button: View() { //Button繼承View
override fun click() = println("Button clicked")
}
Button extends View.
fun View.showOff() = println("I'm a view!")
fun Button.showOff() = println("I'm a button!")
>>> val view: View = Button()
>>> view.showOff() //擴(kuò)展函數(shù)被靜態(tài)地解析
I'm a view!
如你所見戏自,擴(kuò)展函數(shù)并不存在重寫,因為Kotlin會把它們當(dāng)做靜態(tài)函數(shù)對待伤锚。
擴(kuò)展屬性
定義擴(kuò)展屬性擅笔,必須定義getter函數(shù),它沒有默認(rèn)getter的實現(xiàn)屯援。初始化也不可以:因為沒有地方存儲初始值
val String.lastChar: Char
get() = get(length - 1)
聲明一個可變的擴(kuò)展屬性
var StringBuilder.lastChar: Char
get() = get(length - 1) //屬性getter
set(value: Char) {
this.setCharAt(length - 1, value) //屬性setter
}
你可以像訪問使用成員屬性一樣訪問它:
>>> println("Kotlin".lastChar)
n
>>> val sb = StringBuilder("Kotlin?")
>>> sb.lastChar = '!'
>>> println(sb)
Kotlin!
注意猛们,當(dāng)你需要從Java里面訪問擴(kuò)展屬性的時候,你應(yīng)該顯式地調(diào)用它的getter函數(shù):
StringUtilKt.getLastChar(new StringBuilder("Java"))
中綴調(diào)用
val map = mapOf(1 to "one", 7 to "seven", 53 to "fifty-three")
這行代碼中的單詞to
不是內(nèi)置的結(jié)構(gòu)狞洋,而是一種特殊的函數(shù)調(diào)用弯淘,我們稱之為中綴調(diào)用。
以下種調(diào)用方式是等價的:
1.to("one") //一般to函數(shù)的調(diào)用
1 to "one" //使用中綴符號調(diào)用to函數(shù)
使用中綴符號調(diào)用函數(shù)吉懊,你需要使用infix
修飾符來標(biāo)記它庐橙。 下面是一個簡單的to
函數(shù)的聲明:
infix fun Any.to(other: Any) = Pair(this, other)
to
函數(shù)會返回一個Kotlin標(biāo)準(zhǔn)庫中的Pair
的對象