大家好,我是William李梓峰埃儿,歡迎加入我的Kotlin學習之旅截亦。
今天是我學習 Kotlin 的第十天肮疗,內容是 Interfaces - 接口晶姊。
官方文檔:
Interfaces - 接口
Interfaces in Kotlin are very similar to Java 8. They can contain declarations of abstract methods, as well as method implementations. What makes them different from abstract classes is that interfaces cannot store state. They can have properties but these need to be abstract or to provide accessor implementations.
Kotlin 的接口跟 Java 8 的很像。因為 Java 8 的接口除了有抽象方法以外伪货,還可以寫 default method(默認方法们衙,這種機制為了避免一旦更新了接口就要強制讓所有實現類都要實現新的方法钾怔,避免災難的發(fā)生)。接口跟抽象類唯一不同的地方就是接口本身不可以存儲狀態(tài)蒙挑,接口的屬性要么是 abstract 的宗侦,要么需要開發(fā)者提供訪問器(getter setter)的具體實現。
An interface is defined using the keyword interface{: .keyword }
用 interface 關鍵字去定義接口吧:
interface MyInterface {
fun bar()
fun foo() { // 不用像 Java 8 那樣寫 default 忆蚀。矾利。
// optional body
}
}
Implementing Interfaces - 實現接口
A class or object can implement one or more interfaces
跟 Java 一樣,一個類可以實現多個接口馋袜。
class Child : MyInterface { // 這種寫法跟繼承其實沒有任何區(qū)別
override fun bar() {
// body
}
}
Properties in Interfaces - 接口的屬性(重點來了)
You can declare properties in interfaces. A property declared in an interface can either be abstract, or it can provide implementations for accessors. Properties declared in interfaces can't have backing fields, and therefore accessors declared in interfaces can't reference them.
你可以在接口里面聲明屬性男旗。這個聲明在接口里面的屬性可以是抽象的,也可以提供一個具體的訪問器實現(上面提過了)欣鳖。但是察皇,由于接口的屬性即便有訪問器也不可以擁有備用字段(Day 9 講過備用字段,field 只能寫在 setter getter 里面泽台,field 的功能相當于對象的 this 一樣)什荣,所以其訪問器里面不可以調取 field。
interface MyInterface {
val prop: Int // abstract // 默認就有 open 光環(huán)照著
val propertyWithImplementation: String
get() = "foo" // 我是接口屬性的訪問器师痕,就是不可以調 field
fun foo() {
print(prop)
}
}
class Child : MyInterface {
override val prop: Int = 29 // override 就是復寫接口屬性的值
}
Resolving overriding conflicts - 解決復寫的沖突
When we declare many types in our supertype list, it may appear that we inherit more than one implementation of the same method. For example
當我們在超類列表中聲明多個類型的時候溃睹,也許會出現同名方法多種繼承實現的情況(直接看代碼吧而账,這段話有點不知所云)胰坟,例如:
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() // 顯式調用 A 實現
super<B>.foo()
}
override fun bar() {
super<B>.bar()
}
}
Interfaces A and B both declare functions foo() and bar(). Both of them implement foo(), but only B implements bar() (bar() is not marked abstract in A, because this is the default for interfaces, if the function has no body). Now, if we derive a concrete class C from A, we, obviously, have to override bar() and provide an implementation.
接口 A 和 接口 B 都聲明了方法 “foo()” 和 “bar()”。兩個接口都實現了方法 “foo()”泞辐,但是接口 B 實現了 “bar()” (bar() 沒有在 接口 A 中標記為 abstract笔横,因為它沒有具體實現,所以默認就認為是抽象方法咐吼,跟 Java 的一樣嘛)〈档蓿現在,如果我們讓類 C 實現接口 A锯茄,很明顯厢塘,類 C 必須復寫 “bar()” 方法,提供一個具體的實現肌幽。
However, if we derive D from A and B, we need to implement all the methods which we have inherited from multiple interfaces, and to specify how exactly D should implement them. This rule applies both to methods for which we've inherited a single implementation (bar()) and multiple implementations (foo()).
但是晚碾,如果我們讓類 D 實現接口 A 和接口 B ,我們需要實現所有的方法喂急,這些方法均繼承于這些接口格嘁,并且指明類 D如何去實現。這些規(guī)則都適用于所有方法廊移,無論是 “bar()” 還是 “foo()”糕簿。(這里講的有點啰嗦了探入,實際上就是讓類 D 直接復寫所有的方法,這里的情況講的有點復雜了懂诗,實際開發(fā)中基本沒碰到實現不同接口的相同方法名的場景蜂嗽。)
完