Kotlin教學 | 從零開始學Kotlin | Kotlin入門 | CH6: 類別(Class)

類別

類別是一個藍圖或模板,定義產生的物件的屬性(數據)和函數(對數據進行操作的方法)。
類別是抽象的,只提供定義,而根據類別產生的具體實現,則是實際用來操作的物件。

所以會有兩個動作:

類別宣告

class ClassName VisibilityModifier constructor(param1: Type1, param2: Type2) {
    // Member Variables (Properties)
    var mutableProperty: Type1 = initialValue
    val immutableProperty: Type2 = initialValue

    // Member Functions
    fun functionName() {
        // Function body
    }

    // Init block
    init {
        // Initialization logic
    }
}
  • class:關鍵字用於宣告類別。
  • ClassName:類別名稱。
  • class ClassName... {}:宣告類別,如果沒有類別主體,{}可以省略。
  • VisibilityModifier:可見性修飾符,定義了類別的可見性(如 publicprivate 等)。
    可省略,如果省略,則預設為 public
  • constructor(param1: Type1, param2: Type2):宣告類別的主構造函數和它的參數。
    如果構造函數沒有註解或可見性修飾符,則可以省略 constructor 關鍵字,只剩下(...)
    Ex:
    class ClassName():省略 constructor 關鍵字,只剩下(),表示宣告空的參數列表的主構造函數。
    class ClassName:連()都沒有,表示沒有宣告主構造函數。
  • 成員變數(屬性):在類別內宣告的變量
  • 成員函數:在類別內宣告的函數
  • init :關鍵字開始了一個初始化區塊,它在類別的實例化過程中執行。
    初始化區塊通常用來屬性的初始化或其他初始化需要的動作。

Example

class MyClass { // MyClass沒有主構造函數
    var mutableProperty: Int = 10
    val immutableProperty: String = "Hello"
    
    fun myMethod() {
        println("這是一個方法")
    }
}

class Empty // 沒有類別主體,省略大括號{}。

構造函數(Contructor)

構造函數(Constructor)是一種特殊的函數,在創建物件時被自動呼叫。
通常用於初始化物件的狀態,當創建類別的物件時,構造函數就會被自動呼叫,使得物件在使用前擁有有效的初始狀態。

在 Kotlin 中,類別可以擁有一個主構造函數和一個或多個次構造函數。

主構造函數(Primary Constructor)

主構造函數是初始化類別物件及其屬性的機制。
如果主構造函數沒有任何註解或可見性修飾符,則可以省略 constructor 關鍵字

class Person(firstName: String) { /*...*/ }

主構造函數的參數可以在初始化塊中使用,也可以在類別體中宣告的屬性初始化中使用:

class Customer(name: String) {
    val customerKey = name
}

Kotlin 支持從主構造函數同時宣告屬性和初始化的簡潔語法:

class Person(val name: String, var age: Int)

這種宣告還可以包括類別屬性的預設值:

class Person(val name: String, var age: Int = 18)

初始化塊

初始化塊用來在物件呼叫主構造函數時,執行需要的程式邏輯。
這是因為主構造函數只能初始化屬性,不能執行程式邏輯,初始化塊可以視為主構造函數的一部分。
初始化塊使用 init 關鍵字宣告,後面跟著大括號{},在大括號內編寫需要在初始化時執行的程式碼。

初始化塊和屬性初始化會按照它們在類別主體中出現的順序執行:

class InitOrderDemo(name: String) {
    val firstProperty = "First property: $name".also(::println)
    
    init {
        println("First initializer block that prints $name")
    }
    
    val secondProperty = "Second property: ${name.length}".also(::println)
    
    init {
        println("Second initializer block that prints ${name.length}")
    }
}

次構造函數

除了有主構造函數,還可以宣告多個次構造函數。

委派主構造函數

如果類別有宣告主構造函數,每個次構造函數都需要呼叫(委派)到主構造函數,不管是直接呼叫還是間接通過另一個次構造函數呼叫到主構造函數。
次構造函數通過 : this 關鍵字委派函數。
委派確保了在執行到次構造函數時,會先執行主構造函數和初始化塊,然後才執行次構造函數。

class Person (val name: String, val age : Int) {
    constructor(name: String) : this(name, 18) {
        println("name:$name, age:$age")
    }
}

沒有主構造函數,只有次構造函數

如果沒有聲明主構造函數,Kotlin隱式地產生一個無參數的主構造函數,並且在呼叫次構造函數時,自動委派到隱式的主構造函數和初始化塊。

class MyClass {
    init {
        println("Init block is executed")
    }
    
    constructor(i: Int) {
        println("Secondary constructor with parameter $i")
    }
}

沒有宣告任何構造函數

如果一個非抽象類別,沒有任何主要或次要的構造函數,Kotlin將自動生成一個公開的無參數主構造函數。

如果不希望有公開的無參數主構造函數,可以宣告一個可見性為非公開的無參數的空主構造函數。

class DontCreateMe private constructor() { /*...*/ }

創建類別物件和使用成員

在 Kotlin 中,創建類別實例的過程非常直觀,不需要使用 new 關鍵字,這與許多其他語言(如 Java)有所不同。
要創建一個類別的實例,只需像呼叫普通函數那樣直接呼叫其構造函數。

當你想要使用類別的成員(無論是屬性還是方法)時,通過創建該類別的物件,然後使用點(.)符號加上成員名稱的方式來訪問。

class Person(var name: String, var age: Int) {
    fun introduce() {
        println("Hello, my name is $name and I am $age years old.")
    }
}

fun main() {
    // 創建 Person 對象的實例
    val person = Person("Alice", 30)
    
    // 通過使用對象加上 . 符號後面加上成員名稱來訪問屬性和方法
    println(person.name) // 訪問 name 屬性
    println(person.age)  // 訪問 age 屬性
    person.introduce()   // 調用 introduce 方法
}

Reference

https://kotlinlang.org/docs/classes.html

發佈留言