Ste*_*ris 1 kotlin kotlin-delegate
当覆盖由类委托实现的接口方法时,是否可以从覆盖函数中调用通常委托给该类的类?类似于super使用继承时的调用方式。
从文档中:
interface Base {
fun print()
}
class BaseImpl(val x: Int) : Base {
override fun print() { print(x) }
}
class Derived(b: Base) : Base by b
fun main(args: Array<String>) {
val b = BaseImpl(10)
Derived(b).print() // prints 10
}
Run Code Online (Sandbox Code Playgroud)
请注意,重写将按您期望的那样工作:编译器将使用重写实现,而不是委托对象中的实现。
override fun print() { ... }
Run Code Online (Sandbox Code Playgroud)
如何BaseImpl print()从此重写函数中调用该函数?
用例是我想在重用现有实现的同时向此功能添加其他逻辑。
@Egor 的答案有效,并且当委托给的类作为参数(依赖项注入)传递时应该适用。
但是,在我更具体的用例中(抱歉没有在我的问题中明确说明),实现是直接在委托定义中定义的。
class Derived(b: Base) : Base by BaseImpl()
Run Code Online (Sandbox Code Playgroud)
在这种情况下,叶戈尔的回答不起作用,需要更精细的方法。如果您希望隐藏实现,以便调用者无法修改它,则可以使用以下实现。例如,在我的特定用例中,我正在创建一个聚合根并希望保护内部不变量。
open class HiddenBaseImpl internal constructor( protected val _b: Base ) : Base by _b
class Derived() : HiddenBaseImpl( BaseImpl() )
{
override fun print()
{
_b.print()
... do something extra
}
}
Run Code Online (Sandbox Code Playgroud)
由于HiddenBaseImpl的主构造函数只能在内部使用,库的调用者无法实例化此类,因此被迫使用Derived. Derived现在可以调用委托给内部的类并添加额外的行为,而无需调用者传递Base.
由于Base是一个接口,因此您无法真正调用super它(类似于Java)。
相反,您需要声明b为字段并直接使用它:
class Derived(val b: Base) : Base by b {
override fun print() {
b.print()
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1165 次 |
| 最近记录: |