天天看點

Kotlin——繼承

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() { 

//接口的方法預設open 

interface b { 

    fun f() { 

        println("b") 

    fun 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進行顯示标注

屬性也支援覆寫

作者:佚名

來源:51cto