📜  Kotlin接口

📅  最后修改于: 2020-10-05 14:53:16             🧑  作者: Mango

在本文中,您将借助示例学习有关接口以及如何在Kotlin中实现接口的知识。

Kotlin接口类似于Java 8中的接口。它们可以包含抽象方法的定义以及非抽象方法的实现。但是,它们不能包含任何状态。

意思是,接口可能具有属性,但是它必须是抽象的,或者必须提供访问器实现。


推荐读物: Kotlin抽象课

Kotlin中的抽象类与接口相似,但有一个重要区别。抽象类的属性不是抽象的或提供访问器实现是强制性的。


如何定义接口?

关键字interface用于在Kotlin中定义接口。例如,

interface MyInterface {

    var test: String   // abstract property

    fun foo()          // abstract method
    fun hello() = "Hello there" // method with default implementation
}

这里,

  • 创建接口MyInterface
  • 接口具有抽象属性测试和抽象方法foo()
  • 该接口还具有非抽象方法hello()

如何实现接口?

这是类或对象如何实现接口的方法:

interface MyInterface {

    val test: Int   // abstract property

    fun foo() : String   // abstract method (returns String)
    fun hello() {   // method with default implementation
        // body (optional)
    }
}

class InterfaceImp : MyInterface {

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

    // other code
}

在这里,类InterfaceImp实现了MyInterface接口。

该类重写接口的抽象成员( test属性和foo()方法)。


示例:界面如何工作?
interface MyInterface {

    val test: Int

    fun foo() : String

    fun hello() {
        println("Hello there, pal!")
    }
}

class InterfaceImp : MyInterface {

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

}

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

    println("test = ${obj.test}")
    print("Calling hello(): ")

    obj.hello()

    print("Calling and printing foo(): ")
    println(obj.foo())
}

运行该程序时,输出为:

test = 25
Calling hello(): Hello there, pal!
Calling and printing foo(): Lol

如上所述,接口还可以具有提供访问器实现的属性。例如,

interface MyInterface {

    // property with implementation
    val prop: Int
        get() = 23
}

class InterfaceImp : MyInterface {
    // class body
}

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

    println(obj.prop)
}

运行该程序时,输出为:

23

在这里, 道具不是抽象的。但是,它在接口内部有效,因为它为访问器提供了实现。

但是,您不能在接口内部执行类似val prop: Int = 23的操作。


在一个类中实现两个或多个接口

Kotlin不允许真正的多重继承。但是,可以在一个类中实现两个或多个接口。例如,

interface A {

    fun callMe() {
        println("From interface A")
    }
}

interface B  {
    fun callMeToo() {
        println("From interface B")
    }
}

// implements two interfaces A and B
class Child: A, B

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

    obj.callMe()
    obj.callMeToo()
}

运行该程序时,输出为:

From interface A
From interface B

解决覆盖冲突(多个接口)

假设两个接口( AB )具有同名的非抽象方法(例如callMe()方法)。您在一个类中实现了这两个接口(比方说C )。现在,如果使用类C的对象调用callMe()方法,则编译器将引发错误。例如,

interface A {

    fun callMe() {
        println("From interface A")
    }
}

interface B  {
    fun callMe() {
        println("From interface B")
    }
}

class Child: A, B 

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

    obj.callMe()
}

这是错误:

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

要解决此问题,您需要提供自己的实现。这是如何做:

interface A {

    fun callMe() {
        println("From interface A")
    }
}

interface B  {
    fun callMe() {
        println("From interface B")
    }
}

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

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

    obj.callMe()
}

现在,当您运行程序时,输出将是:

From interface A
From interface B

在这里,在类C中提供了callMe()方法的显式实现。

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

语句super.callMe()调用类AcallMe()方法。类似地, super.callMe()调用类BcallMe()方法。