从覆盖内使用 class 委托时调用(基本)委托函数
Calling (base) delegated function when using class delegation from within override
重写由 class delegation 实现的接口方法时,是否可以从重写函数中调用通常委托给的 class?类似于使用继承时调用 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
}
Note that overrides work as you might expect: The compiler will use
your override implementations instead of those in the delegate object.
override fun print() { ... }
如何从这个被覆盖的函数中调用 BaseImpl
print()
函数?
用例是我想向这个函数添加额外的逻辑,同时重用现有的实现。
您可以直接从 属性 b
调用函数 print()
,但为此您需要将简单的构造函数参数 b: Base
更改为将参数保存为 属性private val b: Base
希望对您有所帮助。
由于Base
是一个接口,你不能真正调用super
(类似于Java)。
相反,您需要将 b
声明为字段并直接使用它:
class Derived(val b: Base) : Base by b {
override fun print() {
b.print()
// ...
}
}
并且当委托给的 class 作为参数传递(依赖注入)时应该是合适的。
然而,在我更具体的用例中(很抱歉没有说清楚 ),实现是直接在委托定义中定义的。
class Derived(b: Base) : Base by BaseImpl()
在这种情况下,Egor 的回答不起作用,需要更详细的方法。如果您希望隐藏实现以便调用者无法修改它,则可以使用以下实现。例如,在我的特定用例中,我正在创建一个 aggregate root 并希望保护内部不变量。
open class HiddenBaseImpl internal constructor( protected val _b: Base ) : Base by _b
class Derived() : HiddenBaseImpl( BaseImpl() )
{
override fun print()
{
_b.print()
... do something extra
}
}
由于 HiddenBaseImpl
的主要构造函数只能在内部使用,库的调用者无法实例化此 class,因此被迫使用 Derived
。 Derived
现在可以在内部调用委托给 class 并添加额外的行为,而不允许调用者传递 Base
.
的不同实现
您只能在 Kotlin 中使用 super
来访问超类,不能使用接口或其他奇怪的东西(记住 - Kotlin 在 JVM 上是 运行)。但是,如果将派生实例存储在变量中绝对没问题,例如 .
为避免任何人都可以设置或检索变量,您可以使用私有(或受保护,无论适合您的用例)主构造函数并添加第二个 public 构造函数:
interface Base {
fun print()
}
class BaseImpl() : Base {
override fun print() { print(x) }
}
class Derived private constructor(private val b : Base) : Base by b {
constructor() : this(BaseImpl())
override fun print() = b.print()
}
fun main(args: Array<String>) {
val d = Derived()
d.b // does not work, compiler error
d.print() // prints 10
}
我想我对此有更好的解决方案。
它更优雅,因为不需要额外的 class 并且它与批准的完全相同。
interface Base {
fun print()
}
class Derived private constructor (private val delegate: Base): Base by delegate {
constructor(): this(BaseImpl())
override fun print{
delegate.print()
}
}
重写由 class delegation 实现的接口方法时,是否可以从重写函数中调用通常委托给的 class?类似于使用继承时调用 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
}
Note that overrides work as you might expect: The compiler will use your override implementations instead of those in the delegate object.
override fun print() { ... }
如何从这个被覆盖的函数中调用 BaseImpl
print()
函数?
用例是我想向这个函数添加额外的逻辑,同时重用现有的实现。
您可以直接从 属性 b
调用函数 print()
,但为此您需要将简单的构造函数参数 b: Base
更改为将参数保存为 属性private val b: Base
希望对您有所帮助。
由于Base
是一个接口,你不能真正调用super
(类似于Java)。
相反,您需要将 b
声明为字段并直接使用它:
class Derived(val b: Base) : Base by b {
override fun print() {
b.print()
// ...
}
}
然而,在我更具体的用例中(很抱歉没有说清楚
class Derived(b: Base) : Base by BaseImpl()
在这种情况下,Egor 的回答不起作用,需要更详细的方法。如果您希望隐藏实现以便调用者无法修改它,则可以使用以下实现。例如,在我的特定用例中,我正在创建一个 aggregate root 并希望保护内部不变量。
open class HiddenBaseImpl internal constructor( protected val _b: Base ) : Base by _b
class Derived() : HiddenBaseImpl( BaseImpl() )
{
override fun print()
{
_b.print()
... do something extra
}
}
由于 HiddenBaseImpl
的主要构造函数只能在内部使用,库的调用者无法实例化此 class,因此被迫使用 Derived
。 Derived
现在可以在内部调用委托给 class 并添加额外的行为,而不允许调用者传递 Base
.
您只能在 Kotlin 中使用 super
来访问超类,不能使用接口或其他奇怪的东西(记住 - Kotlin 在 JVM 上是 运行)。但是,如果将派生实例存储在变量中绝对没问题,例如
为避免任何人都可以设置或检索变量,您可以使用私有(或受保护,无论适合您的用例)主构造函数并添加第二个 public 构造函数:
interface Base {
fun print()
}
class BaseImpl() : Base {
override fun print() { print(x) }
}
class Derived private constructor(private val b : Base) : Base by b {
constructor() : this(BaseImpl())
override fun print() = b.print()
}
fun main(args: Array<String>) {
val d = Derived()
d.b // does not work, compiler error
d.print() // prints 10
}
我想我对此有更好的解决方案。 它更优雅,因为不需要额外的 class 并且它与批准的完全相同。
interface Base {
fun print()
}
class Derived private constructor (private val delegate: Base): Base by delegate {
constructor(): this(BaseImpl())
override fun print{
delegate.print()
}
}