Kotlin中的接口和Java 8
很相似。他们可以有抽象方法,也可以有实现的方法。接口和抽象类不同之处在于接口无法存储状态。接口可以有属性,但是属性必须为抽象的或者提供访问实现。
接口使用关键字interface
来定义
interface MyInterface {
fun bar()
fun foo() {
// optional body
}
}
实现接口
类
或者object
能实现一个或多个接口
class Child : MyInterface {
override fun bar() {
// body
}
}
接口中的属性
可以在接口中声明属性,接口中的属性要么声明为抽象,要么给它提供访问实现。接口中声明的属性没有backing fields
,因此无法在存取器中引用它们。
interface MyInterface {
val prop: Int // 抽象属性
//提供访问实现的属性
val propertyWithImplementation: String
get() = "foo"
fun foo() {
print(prop)
}
}
class Child : MyInterface {
override val prop: Int = 29
}
接口的继承
一个接口可以继承其它的接口,因此它既可以实现其它接口的成员,也可以自己声明新的方法和属性。当一个类要实现这样的接口,只需要定义接口所缺失的实现。
interface Named {
val name: String
}
interface Person : Named {
val firstName: String
val lastName: String
override val name: String get() = "$firstName $lastName"
}
data class Employee(
override val firstName: String,
override val lastName: String,
val position: Position) : Person{
//不必实现name属性,因为接口Person已经实现它了
}
解决重写冲突
这个问题和『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()
}
override fun bar() {
super<B>.bar()
}
}
接口A
和 接口B
都声明了foo()
和bar()
方法,他们都实现了方法foo()
,但只有接口B
实现了方法bar()
。现在如果我们从接口A
派生一个类C
,显然,类C
必须重写并实现方法bar()
。
当我们从A
和B
派生一个类D
,我们需要实现从A
和B
继承过来的所有方法, 而且必须指定D
如何实现他们。此规则即适用于继承方法的单个实现(bar()),也适用于继承方法的多个实现(foo())。