本節(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è)類就可以被繼承。
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)造方法。
Child2并沒有primary構(gòu)造方法,,Kotlin中提供了 secondary方法,就可以使用secondary構(gòu)造方法來進(jìn)行初始化。
/**
* 父類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ò)
需要將Fruit中的name 方法開放,使用 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)行修飾。
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