在本文中,您將借助示例學(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()。
這是類或?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 的操作。
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()方法。