在 Kotlin 中代理成员变量的方法、属性

有如下代码

class A {
    fun fun1() {
        println("fun 1 in A")
    }
}

class B {
    val a = A()
}

如果你想在类 B 里实现一个方法 fun1() 交给 a 代理, 最简单的办法是:

class B {
    val a = A()
    fun fun1() {
        a.fun1()
    }
}

但是需要代理的方法有很多,会出现许多重复的样板代码。Kotlin 提供了一个办法来简单的实现代理,但是你得首先声明一个接口,这个接口中要定义好所有你想代理的方法,同时让 AB 都实现该接口。因为 B 需要 A 代理这些方法,所以 AB 都有同样的方法,所以实现同一个接口挺合理:

interface Fun1 {
    fun fun1()
}

class A : Fun1 {
    override fun fun1() {
        println("fun 1 in A")
    }
}

class B : Fun1 {
    val a = A()
    override fun fun1() {
        //...
    }
}

然后把 B 的方法代理给 a, 需要把成员变量 a 定义在构造方法的参数里,否则访问不到 a

class B(val a: A) : Fun1 by a

当然 a 也可以不是成员变量,不过这样似乎没什么意义:

class B(a: A) : Fun1 by a

这样就完成了。同样,属性也可以被代理:

interface PageMeta {
    val totalPages: Int
    val currentPage: Int
}

data class BasePageMeta(
    val count: Int,
    val previousPage: Int,
    val nextPage: Int,
    override val totalPages: Int,
    override val currentPage: Int
) : PageMeta

data class PagedStuffListResponse(
    val meta: BasePageMeta,
    // ...
) : PageMeta by meta