Kotlin 教學【從零開始學 Kotlin 程式設計】類別初始化 (Init and Constructors) 與 lateinit & lazy 使用範例與介紹

【從零開始學 Kotlin 程式設計】
線上教學課程目錄:https://bit.ly/2Kx7GrM
Youtube 課程播放清單:https://bit.ly/3qJ5a5Q

類別初始化

在 Kotlin 中,類別有一個「init」主構造函數和一個或多個「constructor」」次構造函數。主構造函數定義,範例如下:

class MyClass(val arg1: String, var arg2: Int) {
    // 在類頭中定義了主構造函數,arg1 和 arg2 都是主構造函數的參數
    // 主構造函數可以直接在類頭中初始化成員變量
    val myProperty = "HKT線上教室"

    init {
        // init 程式區塊會在主構造函數執行時被調用
        // 在 init 程式區塊中可以執行一些額外的初始化操作,例如驗證輸入參數等
    }
}

次要構造函數定義,範例如下:

class MyClass(val arg1: String, var arg2: Int) {
    constructor(arg1: String) : this(arg1, 0) {
        // 這是一個次構造函數,接收一個字符串參數,將 arg2 初始化為 0
    }

    constructor(arg1: String, arg2: Int, arg3: Boolean) : this(arg1, arg2) {
        // 這是另一個次構造函數,接收三個參數,並調用主構造函數進行初始化
        // 在這個構造函數中可以進行一些額外的初始化操作
    }
}

主要與次要構造函數被呼叫順序,範例如下:

class Account {
    //戶名
    var name: String = ""

    init {
        println("初始化,第一層")
    }

    constructor() {
        println("初始化,第二層")
    }
}

fun main() {
    //實體化
    val account = Account()

    account.name = "HKT"
    println(account.name)
}

輸出結果

初始化,第一層
初始化,第二層
HKT

延遲初始化:lateinit

在 Kotlin 中,我們使用 lateinit 關鍵字來定義為延遲初始化,有用到時,需手動加載。

class MyClass {
//    lateinit 不能使用 val 因為之後不能再修改
//    lateinit val result: String

    lateinit var result: String //lateinit 先定義,稍後在初始化資料值

    fun setResult() {
        result = "初始化資料成功"
    }

    fun showResult() {
//        危險寫法
//        println("result: $result")

//        縱使寫 null 前置判斷仍然會噴錯,因為只要訪問到未初始化資料就會錯誤
//        if (result != null) {
//            println("result: $result")
//        }

        //安全寫法,使用 isInitialized 判斷是否已經初始化
        if (::result.isInitialized) {
            println("result: $result")
        } else {
            println("例外:資料尚未初始化")
        }

    }
}

fun main() {
    val myClass = MyClass()

//    會噴錯,因為沒有初始化資料
//    myClass.showResult()

//    當今天有用到時,需要先「手動加載」
    myClass.setResult()
    myClass.showResult()
}

懶加載:lazy

在 Kotlin 中,我們使用 lazy 關鍵字來達到懶加載,有用到時,會自動加載。

class MyClass {
    //  一般方式
//    val result = getResultData()

    //  懶加載
    val result by lazy {
        getResultData()
    }

    private fun getResultData(): String {
        println("準備開始下載")
        println("資料下載中....")
        println("資料下載中....")
        println("資料下載中....")
        println("下載完成")
        return "資料成功下載"
    }

}

fun main() {
    val myClass = MyClass()
    Thread.sleep(3000)
    println("result: " + myClass.result)
}

餓漢式 & 懶漢式初始化方式比較

  • 餓漢式:

    不管餓不餓都先叫 100 份 pizza。提前先消耗佔住記憶體,但可能一輩子也不會用到。

  • 懶漢式:

    今天肚子餓了才叫 pizza。有需要時才去創建實體化。有效的利用記憶體空間,不會造成不必要的記憶體消耗。


那這次的課程就介紹到這邊囉~

順帶一提,KT 線上教室,臉書粉絲團,會不定期發佈相關資訊,不想錯過最新資訊,不要忘記來按讚,加追蹤喔!也歡迎大家將這套課程分享給更多人喔。

我們下次再見囉!!!掰掰

這個網誌中的熱門文章

16天記下7000單字

2023 最新入門零基礎 Kotlin教學【從零開始學 Kotlin 程式設計】Kotlin 教學課程目錄 (Android Kotlin, IntelliJ IDEA, Android Studio, Android APP 開發教學)

nano 文字編輯器

2022 最新入門零基礎 Flutter教學 【Flutter 程式設計入門實戰 30 天】Flutter 教學課程目錄 (IntelliJ IDEA 開發教學)

【從零開始學 Flutter 程式設計】SharedPreferences 設定檔資料存取