Kotlin---擴展

介紹

除了與Java類比的這些功能之外,Kotlin還新增了一些新的概念

  • 數據類(data)
  • 擴展函數
  • 密封類(sealed)
  • 匿名類
  • 伴生對象(Companion)

數據類

通過data關鍵字來定義數據類。通常用來定義純數據類型的結構體。定義的數據類只能有一個主構造函數定義該數據類中的變量。而在該類中,可以定義函數

data class Date(var year: Int = 10,
                var month: Int,
                var day: Int) {

    fun getDay(): String {
        return "year:$year...month:$month...day:$day"
    }
}

擴展函數

在Java中,如果有一個數據類需要轉換成各種格式的結構,或者需要對屬性做一些處理返回,通常會通過util或者wrappe來對數據結構做封裝。而在Kotlin中提供了擴展函數可以來完成這一些操作。

我們可以在使用的類中,通過以下方式來定義類的擴展函數。但是該擴展函數的使用範圍僅在這個類中使用。而該函數內有this指針,代表着調用該函數的對象,可以直接訪問這個對象的成員

fun ClassName.Function():ReturnType{
     // TODO
}

例如:接上述代碼,有一個類Date代表日期,在Child類中,代表生日,而在Product類中代表生產日期。那麼就可以:

open class Child(name: String, age: Int = 18) : AbsPerson(name) {
    override var mAge = age
    
    fun childBirthDay(date: Date): String {
        return date.birthDay()
    }

    fun Date.birthDay(): String {
        return "Child BirthDay ${this.getDay()}...${this.year}"
    }
}

而在Product類中,可以直接通過Date.craeteDay來調用:

class Product {
    fun createDay(date: Date) {
        date.creatDay()
    }

    fun Date.creatDay() {
        this.getDay()
    }
}

通過擴展函數的方式來完成對與數據類以及其他類的隔離,保證各個類之間的隔離。同樣,Kotlin也支持擴展屬性,與函數類似定義。

密封類

密封類用來表示受限制的類繼承結構。由於enum每一個實例都是一個常量,所以密封類被開發,密封類的子類可以有多個實例。

聲明密封類後,也可以定義多個子類,但是這些子類都需要在與密封類同一個文件中。

// 聲明SealedClass類
sealed class SealedClass
// 定義數據類繼承自SealedClass
data class SealedDataClass(var data: Int) : SealedClass()
// 定義通用類繼承自SealedClass
class SealedConstClass : SealedClass()

而它的用處最經典的是,在when子句中判斷類型

fun choose(data: SealedClass) {
        when(data){
            is SealedConstClass -> data.hashCode()
            is SealedDataClass -> data.value
        }
}

匿名類

Java中可以通過new關鍵字創建匿名類,而Kotlin中則通過object關鍵字來定義匿名類。

通過函數返回的匿名對象必須是private聲明的函數。否則無法解析。而匿名類也可以繼承類:

class Teenager {

    fun runFast() {
        var round = object {
            var time: Long = 0
            var distance: Long = 0
        }
        round.time = 10
        round.distance = 100

        var round2 = runFast2()
        round2.distance = 100
        round2.time = 10
        round2.walk()

    }

    private fun runFast2() = object : Child("Bob") {
        var time: Long = 0
        var distance: Long = 0
    }
}

伴生對象(Companion)

用伴生對象聲明的對象,與類沒有什麼關係,可以使用類名直接調用,例如在實現單例的時候可以直接使用。

class Teenager private constructor() {

    companion object Teen {
        var teenager: Teenager = Teenager()
    }

    fun runFast() {
        Log.e("Tag", "runFast")
    }
}

在使用的時候,可以直接訪問並且調用

Teenager.teenager.runFast()

如果不使用companion修飾的話,則需要調用

Teenager.Teen.teenager.runFast()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章