Kotlin 語(yǔ)法基礎(chǔ)大全巫湘,從例子著手的 從0到1的學(xué)習(xí) -- 基礎(chǔ)介紹
Kotlin 語(yǔ)法基礎(chǔ)大全犀被,從例子著手的 從0到1的學(xué)習(xí) -- 流程控制
Kotlin 語(yǔ)法基礎(chǔ)大全娄猫,從例子著手的 從0到1的學(xué)習(xí) -- 特殊的類
Kotlin 語(yǔ)法基礎(chǔ)大全贱除,從例子著手的 從0到1的學(xué)習(xí) -- 函數(shù)
Kotlin 語(yǔ)法基礎(chǔ)大全,從例子著手的 從0到1的學(xué)習(xí) -- 集合
Kotlin 語(yǔ)法基礎(chǔ)大全媳溺,從例子著手的 從0到1的學(xué)習(xí) -- 作用域
Kotlin 語(yǔ)法基礎(chǔ)大全月幌,從例子著手的 從0到1的學(xué)習(xí) -- 代理
Kotlin 語(yǔ)法基礎(chǔ)大全,從例子著手的 從0到1的學(xué)習(xí) -- 產(chǎn)品級(jí)特性
翻譯來(lái)源
Data Class
Data class 可以用于創(chuàng)建一個(gè)數(shù)據(jù)類用于存儲(chǔ)數(shù)據(jù)悬蔽。這些類將會(huì)自動(dòng)提供類似setter
, getter
,copy
,toString()
,hashCode()
,componentN()
方法
data class User(val name: String, val id: Int) // 1
fun main() {
val user = User("Alex", 1)
println(user) // 2
val secondUser = User("Alex", 1)
val thirdUser = User("Max", 2)
println("user == secondUser: ${user == secondUser}") // 3
println("user == thirdUser: ${user == thirdUser}")
println(user.hashCode())
println(secondUser.hashCode()) // 4
println(thirdUser.hashCode())
// copy() function
println(user.copy()) // 5
println(user.copy("Max")) // 6
println(user.copy(id = 2)) // 7
println("name = ${user.component1()}") // 8
println("id = ${user.component2()}")
}
/*
User(name=Alex, id=1)
user == secondUser: true
user == thirdUser: false
63347075
63347075
2390846
User(name=Alex, id=1)
User(name=Max, id=1)
User(name=Alex, id=2)
name = Alex
id = 1
*/
- 1 定義一個(gè)data class
- 2
println
輸出 dataclass 的toString()
方法的返回值 - 3 自動(dòng)編碼的
equals()
方法將會(huì)考慮如果雙方實(shí)例所有屬性全部相等扯躺,那么者兩個(gè)實(shí)例將會(huì)相等 - 4 相等的 dataclass hashcode 在equals的情況下也會(huì)返回相同的hashcode
- 5 自動(dòng)編碼的
copy()
方法將會(huì)簡(jiǎn)便的創(chuàng)建一份副本 - 6 當(dāng)你選擇拷貝的時(shí)候,你可以便捷的修改內(nèi)部屬性蝎困。你可以按照構(gòu)造函數(shù)的順序依次傳入相應(yīng)的值
- 7 你也可以通過(guò)命名參數(shù)的方式來(lái)修改某個(gè)特定的參數(shù)
- 8 自動(dòng)編碼的
componentN()
方法录语,可以讓你以定義屬性的順序來(lái)依次地讀取各個(gè)字段的值
Enum class 枚舉
枚舉類 等同于java中地枚舉
enum class State {
IDLE, RUNNING, FINISHED // 1
}
fun main() {
val state = State.RUNNING // 2
val message = when (state) { // 3
State.IDLE -> "It's idle"
State.RUNNING -> "It's running"
State.FINISHED -> "It's finished"
}
println(message)
}
- 1 定義具有三個(gè)實(shí)例地枚舉類,每個(gè)實(shí)例都是唯一且固定地禾乘,枚舉的數(shù)量也是固定不可變的钦无。
- 2 可以訪問(wèn)一個(gè)枚舉實(shí)例通過(guò)他的類名。
- 3 本倆當(dāng)when 當(dāng)作表達(dá)式的時(shí)候是需要明確使用else 字段的盖袭。但是當(dāng)when 表達(dá)式遇到 枚舉的時(shí)候失暂,只要你列舉了所有的額枚舉變量,那么你就不需要else 字段了
枚舉類鳄虱,也可以像Java 那樣在類里面定義方法字段等弟塞。這種情況你需要明確的使用分號(hào)來(lái)分割 枚舉的實(shí)例和類里的其他要素。
enum class Color(val rgb: Int) { // 1
RED(0xFF0000), // 2
GREEN(0x00FF00),
BLUE(0x0000FF),
YELLOW(0xFFFF00);
fun containsRed() = (this.rgb and 0xFF0000 != 0) // 3
}
fun main() {
val red = Color.RED
println(red) // 4
println(red.containsRed()) // 5
println(Color.BLUE.containsRed()) // 6
}
- 1 定義一個(gè)枚舉類拙已,具有一個(gè)屬性和一個(gè)方法
- 2 每個(gè)實(shí)例决记,都必須傳遞一個(gè)明確的不相同的屬性值
- 3 方法需要用分號(hào)和實(shí)力定義分隔開(kāi)
- 4 默認(rèn)生成的
toString
方法,默認(rèn)使用枚舉的名字倍踪,比如這里將會(huì)打印出RED
系宫。 - 5 這里會(huì)調(diào)用當(dāng)前實(shí)例的
containsRed
方法 - 6 你也可以通過(guò)類名來(lái)讀取實(shí)例,然后再調(diào)用他的方法
密封類 Sealed Classes
密封類 密封類用于限制繼承建车。如果你定義了一個(gè)密封類扩借,那么他的子類必須定義在同一個(gè)文件中。不允許子類定義在別的文件中缤至,
sealed class Mammal(val name: String) // 1
class Cat(val catName: String) : Mammal(catName) // 2
class Human(val humanName: String, val job: String) : Mammal(humanName)
fun greetMammal(mammal: Mammal): String {
when (mammal) { // 3
is Human -> return "Hello ${mammal.name}; You're working as a ${mammal.job}" // 4
is Cat -> return "Hello ${mammal.name}" //5
is Mammal -> return "Hello ${mammal.name}"
} //6
}
fun main() {
println(greetMammal(Cat("Snowy")))
println(greetMammal(Human("John", "IT")))
//println(greetMammal(Mammal("John"))) // 7
}
/*
Hello Snowy
Hello John; You're working as a IT
*/
- 1 定義一個(gè)密封類
- 2 定義一個(gè)他的子類潮罪,這個(gè)子類必須定義在同一個(gè)文件中
- 3 在這個(gè)方法中,when 表達(dá)式 不需要定義 else 的字段,是因?yàn)楦F舉了 所有的可能性嫉到,這里有人會(huì)問(wèn)了Mammal 不算嘛沃暗,其實(shí)是因?yàn)槟銊?chuàng)建不出來(lái) Mammal 這個(gè)類,7 這里會(huì)報(bào)錯(cuò)
Cannot access '<init>': it is private in 'Mammal' Sealed types cannot be instantiated
- 4 這里將會(huì)發(fā)生一個(gè)快速的強(qiáng)制轉(zhuǎn)化何恶,將 Mammal 轉(zhuǎn)化為 Human
- 5 這里將會(huì)發(fā)生一個(gè)快速的強(qiáng)制轉(zhuǎn)化孽锥,將 Mammal 轉(zhuǎn)化為 Cat
- 6 這里不需要else 字段,因?yàn)樗械?子類都以及明確地覆蓋了
- 7 這句話將會(huì)報(bào)錯(cuò)
Object Keyword
類和對(duì)象在kotlin中和別的面向?qū)ο蟮恼Z(yǔ)言中大同小異:class 是一個(gè)藍(lán)圖细层,object 是類的一個(gè)實(shí)例忱叭。通常來(lái)說(shuō),你定義了一個(gè)類今艺,然后創(chuàng)建多個(gè)類的實(shí)例韵丑。
import java.util.Random
class LuckDispatcher { //1
fun getNumber() { //2
var objRandom = Random()
println(objRandom.nextInt(90))
}
}
fun main() {
val d1 = LuckDispatcher() //3
val d2 = LuckDispatcher()
d1.getNumber() //4
d2.getNumber()
}
- 1 定義一個(gè)藍(lán)圖
- 2 定義一個(gè)方法
- 3 創(chuàng)建一個(gè)藍(lán)圖的實(shí)例
- 4 調(diào)用實(shí)例的方法
在kotlin中中你有這么一個(gè)定義object keyword。這常常被用來(lái)定義 一個(gè)唯一的實(shí)現(xiàn)虚缎。這在Java中撵彻,你可以理解為單例模式:當(dāng)有兩個(gè)線程想要?jiǎng)?chuàng)建這個(gè)類的實(shí)例的時(shí)候,能保證只有同時(shí)只有一個(gè)實(shí)例实牡。
在kotlin中陌僵,你只需要申明一個(gè)
object :
沒(méi)有類定義,沒(méi)有構(gòu)造方法创坞,只有一個(gè)lazy 的實(shí)例碗短。why lazy?因?yàn)樗粫?huì)在被訪問(wèn)到的時(shí)候才會(huì)被創(chuàng)建题涨,另一方面來(lái)說(shuō):他甚至可能不會(huì)被創(chuàng)建
object
Expression
這是一個(gè)object
Expression 基礎(chǔ)的用法,:一個(gè)簡(jiǎn)單的object或者數(shù)據(jù)的結(jié)構(gòu)體偎谁。在這里你不需要定義一個(gè)類的申明:你只需要?jiǎng)?chuàng)建一個(gè)object然后申明他的成員,并且在一個(gè)方法中去使用他纲堵。想這樣的對(duì)象巡雨,在Java中會(huì)以匿名內(nèi)部類的實(shí)例存在。
fun rentPrice(standardDays: Int, festivityDays: Int, specialDays: Int): Unit { //1
val dayRates = object { //2
var standard: Int = 30 * standardDays
var festivity: Int = 50 * festivityDays
var special: Int = 100 * specialDays
}
val total = dayRates.standard + dayRates.festivity + dayRates.special //3
print("Total price: $$total") //4
}
fun main() {
rentPrice(10, 2, 1) //5
}
- 1 創(chuàng)建一個(gè)方法席函,帶有三個(gè) 參數(shù)
- 2 創(chuàng)建一個(gè)object 并計(jì)算保存三個(gè)結(jié)果
- 3 訪問(wèn)這個(gè)object的結(jié)構(gòu)體里面的值
- 4 打印結(jié)果
- 5 運(yùn)行這個(gè)方法铐望,只有在運(yùn)行這個(gè)方法的時(shí)候這個(gè)object 才會(huì)被創(chuàng)建
object
Declaration
你也可以用 object 申明,這不是一個(gè)表達(dá)式茂附,不能用于賦值語(yǔ)句正蛙,你最好通過(guò)類名直接訪問(wèn)他的成員
object DoAuth { //1
fun takeParams(username: String, password: String) { //2
println("input Auth parameters = $username:$password")
}
}
fun main(){
DoAuth.takeParams("foo", "qwerty") //3
}
- 1 創(chuàng)建一個(gè)object 的申明
- 2 在object 中定義一個(gè)方法
- 3 執(zhí)行,在這里object 才會(huì)被真正的創(chuàng)建营曼。
Companion Objects內(nèi)部object
申明在類的內(nèi)部的另一種object的用法是 Companion Objects乒验。從語(yǔ)法上來(lái)講,這更像是java中的靜態(tài)方法溶推。如果你想在kotlin中使用Companion Object徊件。請(qǐng)使用包級(jí)別的類方法定義。
class BigBen { //1
companion object Bonger { //2
fun getBongs(nTimes: Int) { //3
for (i in 1 .. nTimes) {
print("BONG ")
}
}
}
}
fun main() {
BigBen.getBongs(12) //4
}
- 1 定義一個(gè)class
- 2 定義一個(gè) companion 蒜危,顯示的定義了名字
- 3 定義了一個(gè)companion object方法虱痕,
- 4 通過(guò)companion object 的類名直接 訪問(wèn)他的方法