Kotlin——繼承
Kotlin中所有的類(lèi)都有一個(gè)公有的超類(lèi):Any,這是所有沒(méi)有聲明超類(lèi)的類(lèi)的默認(rèn)父類(lèi)。
- class Example //隱式繼承自Any
Any!=Java.lang.Object。尤其,除了equals()、hashCode()和toString()三個(gè)方法外,沒(méi)有任何成員。
為了顯式地聲明超類(lèi),語(yǔ)法如下:
- open class Base(p:Int)
- class Derived(p:Int):Base(p)
如果類(lèi)具有主構(gòu)造器,則可以使用主構(gòu)造器的參數(shù)(并且必須)初始化父類(lèi)。
如果類(lèi)沒(méi)有主構(gòu)造器,那么每個(gè)輔助構(gòu)造器初始化時(shí)需要使用super關(guān)鍵字,或者將其委托給其他構(gòu)造器。需要注意的是,在這種情況下,不同的輔助構(gòu)造器可以調(diào)用基類(lèi)的不同構(gòu)造器。
- class MyView:View{
- constructor(ctx:Context):super(ctx)
- constructor(ctx:Context,attrs:AttributeSet):super(ctx,attrs)
- }
open注解和Java的final相反:它允許其他類(lèi)繼承自該類(lèi)。默認(rèn)的,Kotlin中所有的類(lèi)是final的,也就是說(shuō)不能繼承的。
覆寫(xiě)方法
Kotlin總是做一些明確的事情,不像Java,Kotlin要求復(fù)寫(xiě)方法時(shí)需要顯式的注解和重寫(xiě):
- open class Base {
- open fun v() {
- println("Base.v()")
- }
- fun nv() {
- println("Base.nv")
- }
- }
- class Derived() : Base() {
- override fun v() {
- println("Derived.v()")
- }
- }
復(fù)寫(xiě)Derived的v()時(shí),ovverride注解是必須的,否則編譯器會(huì)報(bào)錯(cuò)。如果沒(méi)有open注解,比如Base的nv(),那么在子類(lèi)中是不能覆寫(xiě)該方法的。在一個(gè)final類(lèi)中(沒(méi)有open注解聲明),open成員是禁止的。也就是說(shuō)final類(lèi)的每個(gè)成員也都是final的。
一個(gè)標(biāo)記為override的成員自身就是open的,子類(lèi)仍然可以覆寫(xiě)它。如果你想禁止覆寫(xiě),那么使用final
- open class AnotherDerived() : Base() {
- final override fun v() {
- println("AnotherDerived.v")
- }
- }
***,main()驗(yàn)證多態(tài)性:
- fun main(args: Array<String>) {
- var base1: Base = Base()
- var base2: Base = Derived()
- var base3: Base = AnotherDerived()
- base1.v()
- base2.v()
- base3.v()
- }
覆寫(xiě)屬性
覆寫(xiě)屬性和覆寫(xiě)方法基本類(lèi)似;如果子類(lèi)要重新聲明父類(lèi)中已經(jīng)聲明過(guò)的屬性,那么需要使用override,并且類(lèi)型要兼容。每個(gè)聲明的屬性可以被具有初始化器的屬性或具有g(shù)etter方法的屬性覆蓋。
- open class Foo {
- open val x: Int
- get() {
- println("Foo")
- return 3
- }
- }
- class Bar1 : Foo() {
- override val x: Int = 2
- }
可以使用var屬性覆蓋val屬性,反之不可以。因?yàn)関al屬性基本上聲明一個(gè)getter方法,并將其替換為var,另外在派生類(lèi)中聲明一個(gè)setter方法。
可以在主構(gòu)造器使用override覆蓋屬性
- interface Aoo {
- val count: Int
- }
- class Aoo1(override val count: Int) : Aoo
- class Aoo2 : Aoo {
- override var count: Int = 0
- }
覆寫(xiě)準(zhǔn)則
在Kotlin中,實(shí)現(xiàn)繼承由以下規(guī)則控制:如果類(lèi)從其直接超類(lèi)繼承同一成員的多個(gè)實(shí)現(xiàn),則它必須覆蓋該成員并提供自己的實(shí)現(xiàn)(可能使用其中一個(gè)繼承)。 要表示從其繼承的實(shí)現(xiàn)的超類(lèi)型,可在尖括號(hào)中使用超類(lèi)型名稱(chēng)超級(jí)限定,例如,super。
- open class A {
- open fun f() {
- println("A")
- }
- fun a() {
- println("a")
- }
- }
- //接口的方法默認(rèn)open
- interface B {
- fun f() {
- println("B")
- }
- fun b() {
- println("b")
- }
- }
- class C() : A(), B {
- override fun f() {
- super<A>.f()
- super<B>.f()
- println("C")
- }
- }
上面的代碼繼承自A和B是沒(méi)有問(wèn)題的,a()和b()因?yàn)镃知道繼承自哪一個(gè)類(lèi)。但是對(duì)于f(),我們有兩個(gè)繼承,所以我們需要覆寫(xiě)f(),并且需要提供我們的實(shí)現(xiàn)來(lái)消除歧義。
總結(jié)
Kotlin中的類(lèi)默認(rèn)是final的,如果需要子類(lèi)繼承,需要使用open修飾;
Kotlin中的方法默認(rèn)是不允許復(fù)寫(xiě)的,只有用open修飾時(shí),子類(lèi)才可以進(jìn)行覆寫(xiě),并且需要使用override進(jìn)行顯示標(biāo)注
屬性也支持覆寫(xiě)