Kotlin——繼承

hbsz51zyqc 7年前發布 | 17K 次閱讀 Kotlin

Kotlin中所有的類都有一個公有的超類:Any,這是所有沒有聲明超類的類的默認父類。

class Example //隱式繼承自Any 

Any!=Java.lang.Object。尤其,除了equals()、hashCode()和toString()三個方法外,沒有任何成員。

為了顯式地聲明超類,語法如下:

open class Base(p:Int) 
 
class Derived(p:Int):Base(p) 

如果類具有主構造器,則可以使用主構造器的參數(并且必須)初始化父類。

如果類沒有主構造器,那么每個輔助構造器初始化時需要使用super關鍵字,或者將其委托給其他構造器。需要注意的是,在這種情況下,不同的輔助構造器可以調用基類的不同構造器。

class MyView:View{ 
 
constructor(ctx:Context):super(ctx) 
 
constructor(ctx:Context,attrs:AttributeSet):super(ctx,attrs) 
 
} 

open注解和Java的final相反:它允許其他類繼承自該類。默認的,Kotlin中所有的類是final的,也就是說不能繼承的。

覆寫方法

Kotlin總是做一些明確的事情,不像Java,Kotlin要求復寫方法時需要顯式的注解和重寫:

open class Base { 
    open fun v() { 
        println("Base.v()") 
    } 
 
    fun nv() { 
        println("Base.nv") 
    } 
 
} 
 
class Derived() : Base() { 
 
    override fun v() { 
        println("Derived.v()") 
    } 
 
} 

復寫Derived的v()時,ovverride注解是必須的,否則編譯器會報錯。如果沒有open注解,比如Base的nv(),那么在子類中是不能覆寫該方法的。在一個final類中(沒有open注解聲明),open成員是禁止的。也就是說final類的每個成員也都是final的。

一個標記為override的成員自身就是open的,子類仍然可以覆寫它。如果你想禁止覆寫,那么使用final

open class AnotherDerived() : Base() { 
    final override fun v() { 
        println("AnotherDerived.v") 
    } 
} 

最后,main()驗證多態性:

fun main(args: Array<String>) { 
 
    var base1: Base = Base() 
    var base2: Base = Derived() 
    var base3: Base = AnotherDerived() 
 
    base1.v() 
    base2.v() 
    base3.v() 
 
} 

覆寫屬性

覆寫屬性和覆寫方法基本類似;如果子類要重新聲明父類中已經聲明過的屬性,那么需要使用override,并且類型要兼容。每個聲明的屬性可以被具有初始化器的屬性或具有getter方法的屬性覆蓋。

open class Foo { 
    open val x: Int 
        get() { 
            println("Foo") 
            return 3 
        } 
} 
 
class Bar1 : Foo() { 
    override val x: Int = 2 
} 

可以使用var屬性覆蓋val屬性,反之不可以。因為val屬性基本上聲明一個getter方法,并將其替換為var,另外在派生類中聲明一個setter方法。

可以在主構造器使用override覆蓋屬性

interface Aoo { 
    val count: Int 
} 
 
class Aoo1(override val count: Int) : Aoo 
 
class Aoo2 : Aoo { 
    override var count: Int = 0 
} 

覆寫準則

在Kotlin中,實現繼承由以下規則控制:如果類從其直接超類繼承同一成員的多個實現,則它必須覆蓋該成員并提供自己的實現(可能使用其中一個繼承)。 要表示從其繼承的實現的超類型,可在尖括號中使用超類型名稱超級限定,例如,super。

open class A { 
    open fun f() { 
        println("A") 
    } 
 
    fun a() { 
        println("a") 
    } 
 
} 
 
//接口的方法默認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是沒有問題的,a()和b()因為C知道繼承自哪一個類。但是對于f(),我們有兩個繼承,所以我們需要覆寫f(),并且需要提供我們的實現來消除歧義。

總結

Kotlin中的類默認是final的,如果需要子類繼承,需要使用open修飾;

Kotlin中的方法默認是不允許復寫的,只有用open修飾時,子類才可以進行覆寫,并且需要使用override進行顯示標注

屬性也支持覆寫

 

來自:http://developer.51cto.com/art/201708/547047.htm

 

 本文由用戶 hbsz51zyqc 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!