# 接口
Kotlin 中的接口与 Java 8 非常类似。它们可以包含一些抽象方法声明,与方法实现一样。令它们与抽象类不同的地方是接口不能存储状态。它们可以有属性但这需要被抽象或是提供访问器的实现。
接口使用关键字 `interface` 定义
``` kotlin
interface MyInterface {
fun bar()
fun foo() {
// optional body
}
}
```
## 实现接口
类或对象能实现一个或多个接口
``` kotlin
class Child : MyInterface {
override fun bar() {
// body
}
}
```
## 接口中的属性
你可以在接口中声明属性。在接口中声明的属性要么是抽象的,要么它能提供访问器的实现。接口中声明的属性不能有后台字段,因此接口中声明的访问器不能引用它们。
``` kotlin
interface MyInterface {
val property: Int // abstract
val propertyWithImplementation: String
get() = "foo"
fun foo() {
print(property)
}
}
class Child : MyInterface {
override val property: Int = 29
}
```
## 解决覆盖冲突
当我们在我们的超类列表中声明了一些类型,可能会出现我们继承了多个相同方法的实现。例如
``` kotlin
interface A {
fun foo() { print("A") }
fun bar()
}
interface B {
fun foo() { print("B") }
fun bar() { print("bar") }
}
class C : A {
override fun bar() { print("bar") }
}
class D : A, B {
override fun foo() {
super<A>.foo()
super<B>.foo()
}
}
```
接口 *A* 和 *B* 都声明了函数 *foo()* 和 *bar()*。它们都实现 *foo()*,但仅仅 *B* 实现了 *bar()*(*bar() 在 *A* 中没有被标记为抽象,因为如果这个函数没有函数体,接口会默认如此)。现在,如果我们从 *A* 衍生出具体类 *C*,很明显我们必须覆盖 *bar()* 并提供一个实现。而且如果 我们从 *A* 和 *B* 衍生了 *D*,我们不用覆盖 *bar()*,因为我们有继承的它的唯一的实现。但我们已经继承了两个 *foo()* 的实现,因此编译器无法知道该选择哪个,然后会强制我们去覆盖 *foo()* 并说明什么才是我们真正想要的。