kotlin語言學(xué)習(xí)07 ——kotlin繼承與重寫

本節(jié)主要介紹kotlin的繼承和重寫。

1、kotlin的繼承

1.1、kotlin的默認(rèn)是final修飾的

在kotlin中,所有的類在默認(rèn)情況下都是無法被繼承的,與Java是完全相反的。
換句話說,在Kotlin中,所有的類默認(rèn)情況下是final的。
繼承方式如下 :

子類 : 父類   

和C++比較相似,示例如下:

/**
 * 繼承 : extends
 * 在kotlin中,所有的類在默認(rèn)情況下都無法被繼承的,與Java是完全相反的
 * 話句話說,在kotlin中,所有的類默認(rèn)情況下是final的
 */

class Parent(name: String, age: Int) {

}

// 繼承 Parent
class Child(name: String, age: Int) : Parent(name, age) {

}

但是上面程序是報(bào)錯(cuò)的:

父類未開放

1.2、open關(guān)鍵字

open: 與final關(guān)鍵字相反,使用open關(guān)鍵字修飾一個(gè)類,這個(gè)類就可以被繼承。

open關(guān)鍵字修飾后

1.3、如果類沒有primary而繼承

在kotlin中,如果一個(gè)類沒有primary構(gòu)造方法,那么這個(gè)類的每個(gè)secondary構(gòu)造方法就需要通過super關(guān)鍵字來初始化類型,或者通過其他secondary來完成這個(gè)任務(wù),不同的secondary構(gòu)造方法可以調(diào)用父類型不同的構(gòu)造方法。

子類沒有主構(gòu)造方法時(shí)繼承

Child2并沒有primary構(gòu)造方法,,Kotlin中提供了 secondary方法,就可以使用secondary構(gòu)造方法來進(jìn)行初始化。

使用secondary方法初始化柱構(gòu)造方法

/**
 * 父類2
 */
open class Parent2(name: String) {

}

/**
 * 繼承父類2
 *
 * 在kotlin中,如果一個(gè)類沒有primary構(gòu)造方法,那么這個(gè)類的每個(gè)secondary構(gòu)造方法
 * 就需要通過super關(guān)鍵字類初始化類類型,或者通過其他secondary來完成這個(gè)任務(wù)
 * 不同的secondary構(gòu)造方法可以調(diào)用父類型不同的構(gòu)造方法
 */
class Child2 : Parent2 {
    constructor(name: String) : super(name)

}

2、方法重寫

kotlin在重寫上的方法跟 C#很相似。

方法重寫未修飾

2.1 kotlin中open和override關(guān)鍵字的使用

需要顯示的指定override關(guān)鍵字,但還是報(bào)錯(cuò)

使用override關(guān)鍵字修飾后

需要將Fruit中的name 方法開放,使用 open 關(guān)鍵字修飾。

使用open關(guān)鍵字修飾后

kotlin通過關(guān)鍵字強(qiáng)制要求程序表明含義,kotlin 通過這種方式,語義上面更好理解。

2.2、final關(guān)鍵字的使用

如果繼承后的方法不想被子類繼承,可以加上final

/**
 * 橘子類
 */
open class Orange : Fruit() {
    // 如果該方法不想被子類繼承,可以加上final
    final override fun name() {
        println("orange")
    }
}

3、屬性的重寫

Kotlin中屬性的重寫和方法的重寫基本類似。

屬性重未修飾

3.1、kotlin屬性的重寫

同樣需要使用open 關(guān)鍵字和 Override關(guān)鍵字進(jìn)行修飾。

使用open和primary關(guān)鍵字修飾后

3.2、在primary方法中聲明重寫的屬性

/**
 * 在primary方法中聲明重寫的屬性
 */
class MyChild2(override  val name:String):MyParent() {

}

3.3、val與var定義的屬性重寫問題

/**
 * 父類 MyParent3
 */
open class MyParent3 {
    open fun method() {
        println("parent method")
    }

    open val name: String get() = "parent"
}

/**
 * 子類MyChild3
 * 1、val屬性可以 override val屬性
 * 2、val屬性不能 override var屬性
 * 3、var屬性可以 override val屬性
 *
 * 本質(zhì)上,val相當(dāng)于get方法,var相當(dāng)于get,set方法
 * var默認(rèn)為public級(jí)別的定義,相當(dāng)于,擴(kuò)展了 變量的修飾空間
 */
class MyChild3 : MyParent3() {
    override fun method() {
        super.method()
        println("child method")
    }

    override val name: String
        get() = super.name + " and child "
}

在主函數(shù)中調(diào)用:

fun main() {
    val myChild3 = MyChild3()
    myChild3.method()
    println(myChild3.name)
}

結(jié)果 :

parent method
child method
parent and child   
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容