【Kotlin学习日记】Day10:接口

大家好,我是William李梓峰,欢迎加入我的Kotlin学习之旅。
今天是我学习 Kotlin 的第十天,内容是 Interfaces - 接口。

官方文档:

  • https://kotlinlang.org/docs/reference/interfaces.html

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(默认方法,这种机制为了避免一旦更新了接口就要强制让所有实现类都要实现新的方法,避免灾难的发生)。接口跟抽象类唯一不同的地方就是接口本身不可以存储状态,接口的属性要么是 abstract 的,要么需要开发者提供访问器(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 {    // 这种写法跟继承其实没有任何区别
    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 光环照着

    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.foo()     // 显式调用 A 实现
        super.foo()
    }

    override fun bar() {
        super.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如何去实现。这些规则都适用于所有方法,无论是 “bar()” 还是 “foo()”。(这里讲的有点啰嗦了,实际上就是让类 D 直接复写所有的方法,这里的情况讲的有点复杂了,实际开发中基本没碰到实现不同接口的相同方法名的场景。)

你可能感兴趣的:(【Kotlin学习日记】Day10:接口)