Kotlin學(xué)習(xí)(4)類、接口和對(duì)象

4.1 接口的定義

接口使用interface關(guān)鍵字,kotlin中的實(shí)現(xiàn)和繼承使用冒號(hào)代替implementextend

接口定義

//包含一個(gè)抽象方法,這個(gè)抽象方法有默認(rèn)的實(shí)現(xiàn)
interface Clickable{
    fun click() = println("cat is clicked")
}

接口的實(shí)現(xiàn)

class Cat :Clickable{
  //實(shí)現(xiàn)接口里的抽象方法
    override fun click() {

    }
}

如上,kotlin接口的抽象方法可以有一個(gè)默認(rèn)實(shí)現(xiàn),此時(shí)子類可以不用實(shí)現(xiàn)這個(gè)方法,默認(rèn)調(diào)用父類里的方法實(shí)現(xiàn)

注意:如果我們實(shí)現(xiàn)了有重名方法的兩個(gè)接口,此時(shí)必須提供自己的方法實(shí)現(xiàn)

interface Clickable{
    fun click() = println("cat is clicked")
}

interface Focusable{
    fun click() = println("cat is focused")
}

class Cat :Clickable,Focusable{
    override fun click() {
        super<Clickable>.click()
        super<Focusable>.click()
    }
}

使用super<Clickable>.click()調(diào)用接口的方法的實(shí)現(xiàn),在尖括號(hào)里指明調(diào)用的基類的名稱


4.2 繼承控制修飾符

Java中所有的類和方法默認(rèn)是open的,可以繼承和重寫(xiě)的。但是kotlin中默認(rèn)是final的,如果想創(chuàng)建一個(gè)子類,需要用open來(lái)修飾這個(gè)類。而且,需要給每個(gè)需要被重寫(xiě)的方法和屬性添加open修飾符

修飾符 相關(guān)成員 備注
final 不能被重寫(xiě) 類中的成員默認(rèn)使用
open 可以被重寫(xiě) 需要明確的聲明
abstract 可以被重寫(xiě) 修飾抽象類,修飾的抽象成員不能有實(shí)現(xiàn)
override 修飾重寫(xiě)的父類的方法或者參數(shù) 如果沒(méi)有使用final修飾,這個(gè)重寫(xiě)的成員還是開(kāi)放的即open的
//使用open修飾符修飾的類才能被繼承
open class Dog(){
}

4.3 可見(jiàn)性修飾符

Kotlin中的可見(jiàn)性修飾符同樣可以使用:public、protected、private,默認(rèn)可見(jiàn)性為public

  • Java中的默認(rèn)可見(jiàn)性是-包私有,Kotlin只是把包作為代碼的組織方式,并沒(méi)有做可見(jiàn)性的控制
  • Kotlin中提供了一種新的修飾符internal,表示模塊內(nèi)部可見(jiàn),一個(gè)模塊理解為一起編譯的Kotlin文件
  • Kotlin允許在頂層聲明中使用private關(guān)鍵字,包括類、函數(shù)和屬性,只在聲明他們的文件中可見(jiàn)
修飾符 類成員 頂層聲明
public(默認(rèn)) 所有地方可見(jiàn) 所有地方可見(jiàn)
internal 模塊中可見(jiàn) 模塊中可見(jiàn)
protected 子類中可見(jiàn) -
private 類中可見(jiàn) 文件中可見(jiàn)

4.4 內(nèi)部類和嵌套類

Kotlin中可以把類定義在其他類中,但是默認(rèn)是不持有外部類的引用的,叫嵌套類

想要從嵌套類中訪問(wèn)外部類的引用,需要使用inner修飾符將其定義成內(nèi)部類,如下

/**
 * 1.Kotlin中類可以嵌套在其他類中,默認(rèn)是靜態(tài)內(nèi)部類
 * 2.使用inner修飾的內(nèi)部類為非靜態(tài)內(nèi)部類,才可以訪問(wèn)外部類的參數(shù)和引用
 * 3.inner修飾的內(nèi)部類訪問(wèn)外部類的引用時(shí),可以用this@外部類 的方式訪問(wèn)
 */
class OuterClass() {
    val name: String = "haha"

     inner class Inner {

        fun getOutParam() = name

        fun getOutClass() = this@OuterClass.name
    }
}

4.5 密封類

密封類,用來(lái)表示受限的類繼承結(jié)構(gòu):當(dāng)一個(gè)值為有限集中的類型、而不能有其他類型時(shí)。

聲明一個(gè)密封類,用sealed修飾符,而且其子類要和這個(gè)密封類定義在同一個(gè)文件中

sealed class Animal
class Fish() : Animal()
class Sheep() : Animal()

fun switchAnimal(animal: Animal) =
        when (animal) {
            is Fish -> println("this is a fish")
            is Sheep -> println("this is a sheep")
        }

如上,密封類的關(guān)鍵好處在于使用when表達(dá)式時(shí),如果驗(yàn)證語(yǔ)句覆蓋了所有的情況,那么我們不需要再提供else子句了。


4.6 構(gòu)造函數(shù)和初始化塊

Kotlin中構(gòu)造函數(shù)由一個(gè)主構(gòu)造函數(shù)和多個(gè)從構(gòu)造函數(shù)組成

主構(gòu)造函數(shù): 是類頭的一部分,定義在類名后面

class Apple constructor(val size:Float,val color:Int)

當(dāng)主構(gòu)造函數(shù)沒(méi)有注解或者可見(jiàn)性修飾符修飾時(shí)constructor可以省略,由于主構(gòu)造函數(shù)不能包含任何代碼,初始化等代碼可以放在初始化塊init{}

//省略constructor關(guān)鍵字
class Apple(val size:Float,val color:Int){
    init {
        //初始化代碼
    }
}

從構(gòu)造函數(shù):可以聲明多個(gè)前綴為constructor的從構(gòu)造函數(shù)

自定義view通常要寫(xiě)幾個(gè)構(gòu)造函數(shù),MyButton有三個(gè)從構(gòu)造函數(shù),沒(méi)有主構(gòu)造函數(shù)

class MyButton : View {
    //使用this委托給兩個(gè)參數(shù)的構(gòu)造函數(shù)
    constructor(context: Context) : this(context, null)
    //使用this委托給三個(gè)參數(shù)的構(gòu)造函數(shù)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    //使用super調(diào)用父類的構(gòu)造函數(shù),初始化其基類
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        
    }
}

如果類沒(méi)有主構(gòu)造函數(shù),那么每個(gè)從構(gòu)造函數(shù)必須使用super關(guān)鍵字初始化其基類,或者委托另一個(gè)構(gòu)造函數(shù)做到這一點(diǎn)。


?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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