根据我的理解, class 代表团应该这样做
允许对象组合实现与继承相同的代码重用 . [维基百科]
Kotlin支持类委派,并注意以下声明形成documentation:
覆盖按预期工作:编译器将使用覆盖实现而不是委托对象中的覆盖实现 .
考虑到这一点,请考虑以下最小示例:
interface A {
val v: String
fun printV() {
Logger.getLogger().info(Logger.APP, "A", v)
}
}
class AImpl : A {
override val v = "A"
}
class B(a: A) : A by a {
override val v: String = "B"
}
我预计 B(AImpl()).printV()
将打印 B
,但是它打印 A
,即它使用 AImpl
的默认实现 .
此外,如果我使用 super
实现覆盖B中的 printV()
方法,即
class B(a: A) : A by a {
override val v: String = "B"
override fun printV() {
super.printV()
}
}
我现在预计 B(AImpl()).printV()
将打印 A
,但是这次打印 B
. 这似乎违反直觉 .
你能对这种行为给出一个很好的解释吗?
1 回答
这按预期工作 .
总是想象类授权,因为您将自己的调用重定向到委托类:
这清楚地表明,对
printV
的调用只是委托给了a
,并且B
的类在B
中的含义并不重要 .再次,想象一下委托如何在内部工作:
这清楚地表明,
a
不再涉及,printV
使用您的本地重写变量 .Update 1 (elaboration on second part)
https://kotlinlang.org/docs/reference/delegation.html
因此,您不能将委托视为继承 . 是代表团(查找委托模式的维基百科)
因此,您的接口的所有方法(
v
-property和printV
)都只是生成并转发到委托类 .这里是类
B
的代码片段和反编译代码,以查看它在内部如何工作: