Kotlin 類別定義 (Class)
Kotlin 的類別定義非常簡潔。
定義類別
class Person { /* ... */ }
如果沒有內容,連大括號都可以省掉:
class Empty
建構函式 (Constructor)
這是與 Java 差別最大的地方。Kotlin 有 Primary Constructor (主建構子) 和 Secondary Constructor (次建構子)。
Primary Constructor
直接寫在類別名稱後面。這是最推薦的寫法。
// 定義類別同時定義屬性 (val name)
class Person(val name: String, var age: Int)
fun main() {
val p = Person("Miko", 18)
println(p.name)
}
看到那個 val 了嗎?它自動幫你宣告了屬性、並在建構時賦值。一行抵 Java 十行。
初始化區塊 (init)
如果你在建構時需要執行一些邏輯 (例如驗證資料),可以寫在 init 區塊。
class Person(val name: String, var age: Int) {
init {
println("User $name created!")
if (age < 0) age = 0
}
}
}
}
建構子預設值 (Default Arguments)
在 Kotlin 中,不需要像 Java 那樣宣告一大堆 Overloading 的建構函式。你只需要為參數提供預設值即可。
// 如果不傳 age,預設為 0
class Person(val name: String, var age: Int = 0)
fun main() {
val p1 = Person("Miko") // age = 0
val p2 = Person("John", 20) // age = 20
// 甚至可以使用具名參數 (Named Arguments) 來指定特定參數
val p3 = Person(age = 18, name = "Amy")
}
這大大減少了對 Secondary Constructor 的依賴。除非你需要相容 Java 的呼叫,否則盡量使用預設參數。
Secondary Constructor
如果需要多種建構方式,可以使用 constructor 關鍵字。
但注意:如果有定義 Primary Constructor,Secondary Constructor 必須呼叫它 (this(...))。即使用次建構子時,Kotlin 要求你必須先初始化主建構子所定義的屬性。
// 主建構子 (Primary Constructor)
class Person(val name: String) {
var age: Int = 0
// 次建構子 (Secondary Constructor)
// 使用 this() 呼叫主建構子,並初始化 name
constructor(name: String, age: Int) : this(name) {
this.age = age
}
}
建立物件
Kotlin 建立物件 不需要 new 關鍵字!
val p = Person("Miko", 18)
"this" 關鍵字
this 關鍵字代表 當前的物件實體 (Current Receiver)。它的用途主要有:
1. 存取當前類別的成員
當函式參數名稱與屬性名稱發生衝突時,使用 this 來區分。
class Person(name: String) {
var name: String = ""
init {
// this.name 是屬性,name 是參數
this.name = name
}
}
2. 存取外部類別 (Qualified this)
在內部類別 (Inner Class) 或巢狀結構中,如果名稱衝突,我們需要指名要存取哪一層的 this。
語法是 this@Label,其中 Label 通常是類別名稱。
class Outer {
val a = 10
inner class Inner {
val a = 20
fun test() {
val a = 30
println(a) // 30 (區域變數)
println(this.a) // 20 (Inner 的屬性)
println(this@Outer.a) // 10 (Outer 的屬性)
}
}
}
3. 在擴充函式中
在擴充函式中,this 代表被擴充的那個物件實體。
fun String.printMe() {
// 這裡的 this 就是呼叫 printMe 的那個字串
println(this)
}
"Hello".printMe() // 印出 Hello