29.md 5.1 KB
Newer Older
W
wizardforcel 已提交
1 2 3 4 5 6 7 8 9 10 11 12
# Kotlin 接口

> 原文: [https://www.programiz.com/kotlin-programming/interfaces](https://www.programiz.com/kotlin-programming/interfaces)

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

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

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

* * *

W
wizardforcel 已提交
13
**推荐阅读**[Kotlin 抽象类](/kotlin-programming/abstract-class "Kotlin Abstract Class")
W
wizardforcel 已提交
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34

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

* * *

## 如何定义接口?

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

```kt
interface MyInterface {

    var test: String   // abstract property

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

这里,

W
wizardforcel 已提交
35
*   接口`MyInterface`已创建。
W
wizardforcel 已提交
36
*   接口具有抽象属性`test`和抽象方法`foo()`
W
wizardforcel 已提交
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
*   该接口还具有非抽象方法`hello()`

* * *

## 如何实现接口?

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

```kt
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
}

```

W
wizardforcel 已提交
66
在这里,类`InterfaceImp`实现了`MyInterface`接口。
W
wizardforcel 已提交
67

W
wizardforcel 已提交
68
该类覆盖接口的抽象成员(`test`属性和`foo()`方法)。
W
wizardforcel 已提交
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136

* * *

## 示例:接口如何工作?

```kt
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<String>) {
    val obj = InterfaceImp()

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

    obj.hello()

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

运行该程序时,输出为:

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

* * *

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

```kt
interface MyInterface {

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

class InterfaceImp : MyInterface {
    // class body
}

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

    println(obj.prop)
}
```

W
wizardforcel 已提交
137
运行该程序时,输出为:
W
wizardforcel 已提交
138 139 140 141 142

```kt
23
```

W
wizardforcel 已提交
143
在这里,`prop`不是抽象的。 但是,它在接口内部有效,因为它为访问器提供了实现。
W
wizardforcel 已提交
144

W
wizardforcel 已提交
145
但是,您无法在接口内执行类似`val prop: Int = 23`的操作。
W
wizardforcel 已提交
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177

* * *

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

Kotlin 不允许真正的[多重继承](https://en.wikipedia.org/wiki/Multiple_inheritance "Multiple Inheritance")。 但是,可以在一个类中实现两个或多个接口。 例如,

```kt
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<String>) {
    val obj = Child()

    obj.callMe()
    obj.callMeToo()
}
```

W
wizardforcel 已提交
178
运行该程序时,输出为:
W
wizardforcel 已提交
179 180 181 182 183 184 185 186 187 188 189

```kt
From interface A
From interface B

```

* * *

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

W
wizardforcel 已提交
190
假设两个接口(`A``B`)具有同名的非抽象方法(假设`callMe()`方法)。 您在一个类中实现了这两个接口(假设`C`)。 现在,如果使用类`C`的对象调用`callMe()`方法,则编译器将引发错误。 例如,
W
wizardforcel 已提交
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259

```kt
interface A {

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

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

class Child: A, B 

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

    obj.callMe()
}
```

这是错误:

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

* * *

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

```kt
interface A {

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

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

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

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

    obj.callMe()
}
```

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

```kt
From interface A
From interface B
```

W
wizardforcel 已提交
260
在此,在类`C`中提供了`callMe()`方法的显式实现。
W
wizardforcel 已提交
261 262 263 264 265 266 267 268 269 270

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

W
wizardforcel 已提交
271
语句`super<A>.callMe()`调用类`A``callMe()`方法。 类似地,`super<B>.callMe()`调用类`B``callMe()`方法。