# 接口
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()* 并說明什么才是我們真正想要的。