接口

Kotlin 的接口非常类似于 Java8。可以包含抽象方法的声明以及方法的实现。接口与抽象类的区别是不能存储状态。接口可以有属性,但是必须声明为抽象类型或者实现了访问器。

接口通过关键字 interface 来定义:

  1. interface MyInterface {
  2. fun bar()
  3. fun foo() {
  4. // optional body
  5. }
  6. }

实现接口

类或者对象可以实现一个或多个接口:

  1. class Child : MyInterface {
  2. override fun bar() {
  3. // body
  4. }
  5. }

类的属性

在接口中可以声明属性。属性可以是抽象的,或者提供了访问器的实现。接口的属性没有幕后字段,因此访问器不能引用到他们。

  1. interface MyInterface {
  2. val prop: Int // abstract
  3. val propertyWithImplementation: String
  4. get() = "foo"
  5. fun foo() {
  6. print(prop)
  7. }
  8. }
  9. class Child : MyInterface {
  10. override val prop: Int = 29
  11. }

解决覆写冲突

如果父类的列表中有多个类型,我们可能会继承了同一个方法的多个实现。例如:

  1. interface A {
  2. fun foo() { print("A") }
  3. fun bar()
  4. }
  5. interface B {
  6. fun foo() { print("B") }
  7. fun bar() { print("bar") }
  8. }
  9. class C : A {
  10. override fun bar() { print("bar") }
  11. }
  12. class D : A, B {
  13. override fun foo() {
  14. super<A>.foo()
  15. super<B>.foo()
  16. }
  17. override fun bar() {
  18. super<B>.bar()
  19. }
  20. }

接口 A 和 B 都声明了函数 foo()bar()。他们都实现了 foo(),但是只有 B 实现了 bar()bar() 在 A 中没有用 abstract 标记,这是因为接口的函数如果没有函数体,默认就是抽象的)。如果我们现在要继承 A 来实现一个具体的类 C,很明显,必须重载 bar() 并且提供一个实现。

但是,如果我们从 A 和 B 继承一个 D,我们就需要实现从多个接口继承下来的方法,并且要明确地指明 D 应该如何实现它们。这两条同样适用于只继承了单个实现(bar())以及继承了多个实现(foo())的方法。