接口

回到目录
项目源码 kotlin-class 项目


使用 interface 声明一个接口, 接口里可以声明抽象方法, 也可以有方法实现. 跟抽象
类的区别是, 接口不能保存状态(没有 backing field), 可以声明属性但是不能初始化它,
得是抽象属性, 或提供 getter setter 方法. 又因为无法保存状态, 所以 setter 没什么
意义. 所以若不是抽象属性, 一般用 val 并提供 getter.

属性重写可以直接用主构造函数中使用 override, 也可以

interface Ia {
    val va: Int // 抽象属性
    var vb: Int // 抽象属性
    val vc get() = 1 // 提供 getter 的属性
    var vd
        get() = 2
        set(value) {
            println("如果子类重写了 vd 属性, 这里不会执行")
            println("没有 backing field, 不能保存状态, 这么做基本上没意义")
        }
    fun a() // 抽象方法
    fun b() = println("b") // 具体方法, 不用 override
}

class A(override val va: Int, override var vb: Int) : Ia {
    // vc 和 vc 都有实现代码, 所以不必须重写
    // 我们重写个 vd 吧
    override var vd = 2222
    override fun a() {
        println("a")
    }
    // 可以重写, 也可以不重写
    override fun b() {
        super.b()
        println("A b")
    }
}

fun main(args: Array<String>) {
    val objA = A(11, 22)
    println(objA.va) // 11
    println(objA.vb) // 22
    println(objA.vc) // 1
    println(objA.vd) // 2222
    objA.vd = 3 // 如果没重写 vd, 是无法保存状态的, 但是重写了.
    println(objA.vd) // 3
    objA.a() // a
    objA.b()  // b 换行 A b
}

接口继承

接口可以继承其他接口.

interface Ib {
    val b: Int
}
interface Ic: Ib {
    val c: Int
    override val b: Int
        get() = c * 2
}

// 属性 b 已经有实现代码了, 所以不用重写
class D(override val c: Int, val d: Int) : Ic {
}

解决重写冲突问题

// 解决冲突
interface Ie {
    fun f() = println("Ie")
}
interface If {
    fun f() = println("If")
}
class Cg: Ie, If {
    // 必须重写了, 因为不知道要调用哪个 f()
    override fun f() {
        println("Cg")
        // 需要指定调用哪个父类接口的实现方法可以这样
        super<Ie>.f()
        super<If>.f()
    }
}

回到目录

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容