Kotlin 接口(Interface)

在本文中,您將借助示例學(xué)習(xí)有關(guān)接口以及如何在Kotlin中實(shí)現(xiàn)接口的知識(shí)。

Kotlin接口類似于Java 8中的接口。它們可以包含抽象方法的定義以及非抽象方法的實(shí)現(xiàn)。但是,它們不能包含任何狀態(tài)。

也就是說,接口可能有屬性,但它必須是抽象的或者必須提供訪問器實(shí)現(xiàn)。

推薦閱讀: Kotlin 抽象類

Kotlin中的抽象類與接口相似,但有一個(gè)重要區(qū)別。抽象類的屬性不是必須抽象的或提供訪問器實(shí)現(xiàn)的。

如何定義接口?

關(guān)鍵字interface用于在Kotlin中定義接口。例如,

interface MyInterface {

    var test: String   //抽象屬性

    fun foo()          //抽象方法
    fun hello() = "Hello there" //具有默認(rèn)實(shí)現(xiàn)的方法
}

這里,

  • 創(chuàng)建接口 MyInterface。

  • 該接口有一個(gè)抽象屬性 test 和一個(gè)抽象方法 foo()。

  • 該接口還具有非抽象方法 hello()。

如何實(shí)現(xiàn)接口?

這是類或?qū)ο笕绾螌?shí)現(xiàn)接口的方法:

interface MyInterface {

    val test: Int   //抽象屬性
    fun foo() : String   //抽象方法(返回字符串)
    fun hello() {   //具有默認(rèn)實(shí)現(xiàn)的方法
        // body (optional)
    }
}

class InterfaceImp : MyInterface {

    override val test: Int = 25
    override fun foo() = "Lol"

    //其他代碼
}

在這里,InterfaceImp 類實(shí)現(xiàn)了 MyInterface 接口。

該類重寫接口的抽象成員(test屬性 和 foo()方法)。

示例:接口如何工作?

interface MyInterface {

    val test: Int

    fun foo() : String

    fun hello() {
        println("你好,伙計(jì)!")
    }
}

class InterfaceImp : MyInterface {

    override val test: Int = 25
    override fun foo() = "Lol"

}

fun main(args: Array<String>) {
    val obj = InterfaceImp()

    println("test = ${obj.test}")
    print("調(diào)用 hello(): ")

    obj.hello()

    print("調(diào)用和打印 foo(): ")
    println(obj.foo())
}

運(yùn)行該程序時(shí),輸出為:

test = 25
調(diào)用 hello(): 你好,伙計(jì)!
調(diào)用和打印 foo(): Lol

如前面說講,接口還可以具有提供訪問器實(shí)現(xiàn)的屬性。例如,

interface MyInterface {

    //帶實(shí)現(xiàn)的屬性
    val prop: Int
        get() = 23
}

class InterfaceImp : MyInterface {
    //類主體
}

fun main(args: Array<String>) {
    val obj = InterfaceImp()

    println(obj.prop)
}

運(yùn)行該程序時(shí),輸出為:

23

這里,prop 不是抽象的,但是它在接口中是有效的,因?yàn)樗峁┝嗽L問器的實(shí)現(xiàn)。

但是,您不能在接口內(nèi)部執(zhí)行類似 val prop:Int = 23 的操作。

在一個(gè)類中實(shí)現(xiàn)兩個(gè)或多個(gè)接口

Kotlin不允許真正的多重繼承。但是,可以在一個(gè)類中實(shí)現(xiàn)兩個(gè)或多個(gè)接口。例如,

interface A {

    fun callMe() {
        println("來自接口A")
    }
}

interface B  {
    fun callMeToo() {
        println("來自接口B")
    }
}

//實(shí)現(xiàn)兩個(gè)接口A和B
class Child: A, B

fun main(args: Array<String>) {
    val obj = Child()

    obj.callMe()
    obj.callMeToo()
}

運(yùn)行該程序時(shí),輸出為:

來自接口A
來自接口B

解決重寫沖突(多接口)

假設(shè)兩個(gè)接口(A和B)具有相同名稱的非抽象方法(假設(shè)callMe()方法)。您在一個(gè)類中實(shí)現(xiàn)了這兩個(gè)接口(假設(shè)C)。 現(xiàn)在,如果使用 C 類的對(duì)象調(diào)用callMe()方法,則編譯器將引發(fā)錯(cuò)誤。 例如

interface A {

    fun callMe() {
        println("接口 A")
    }
}

interface B  {
    fun callMe() {
        println("接口 B")
    }
}

class Child: A, B 

fun main(args: Array<String>) {
    val obj = Child()

    obj.callMe()
}

這是拋出的錯(cuò)誤:

Error:(14, 1) Kotlin: Class 'C' must override public open fun callMe(): Unit defined in A because it inherits multiple interface methods of it

要解決此問題,您需要提供自己的實(shí)現(xiàn)。這是如何做:

interface A {

    fun callMe() {
        println("接口 A")
    }
}

interface B  {
    fun callMe() {
        println("接口 B")
    }
}

class C: A, B {
    override fun callMe() {
        super<A>.callMe()
        super<B>.callMe()
    }
}

fun main(args: Array<String>) {
    val obj = C()

    obj.callMe()
}

現(xiàn)在,當(dāng)您運(yùn)行程序時(shí),輸出將是:

接口  A
接口  B

這里,在 C 類中提供了callMe()方法的顯式實(shí)現(xiàn)。

class C: A, B {
    override fun callMe() {
        super<A>.callMe()
        super<B>.callMe()
    }
}

語句 super<A>.callMe()調(diào)用類A的callMe()方法。類似地,super<B>.callMe()調(diào)用類B的callMe()方法。

丰满人妻一级特黄a大片,午夜无码免费福利一级,欧美亚洲精品在线,国产婷婷成人久久Av免费高清