至于我的理解,在Kotlin中委托实现的想法是避免看起来像这样的代码:
class MyClass(val delegate : MyInterface) : MyInterface
{
override fun myAbstractFun1() = delegate.myAbstractFun1()
override fun myAbstractFun2() = delegate.myAbstractFun2()
// ...
}
相反,我们可以编写以下代码:
class MyClass(val delegate : MyInterface) : MyInterface by delegate
现在,我希望delegate
是一个可变变量,即我的代码如下:
var delegate : MyInterface = MyImplementation()
object MyObject : MyInterface by delegate
因此,如果我像第一个示例一样将自己的每个抽象方法委托给delegate
,那么更改delegate
的值确实会改变方法的行为。但是,上面的代码编译为此Java代码:
public final class MyObject implements MyInterface {
public static final MyObject INSTANCE;
// $FF: synthetic field
private final MyInterface $$delegate_0 = MyObjectKt.access$getDelegate$p();
@NotNull
public String myAbstractFun1() {
return this.$$delegate_0.myAbstractFun1();
}
@NotNull
public String myAbstractFun2() {
return this.$$delegate_0.myAbstractFun2();
}
}
很明显,Kotlin编译器决定在创建delegate
到最终字段MyObject
时将其复制,而不是仅仅使用$$delegate_0
字段,当我更改时不会修改价值delegate
有没有更好的解决方案,而不是手动委派每个方法?
答案 0 :(得分:1)
可悲的是,据我所知,无法通过更改原始属性内容来更改代理,但您仍然可以通过以不可变的方式进行复制并执行类似操作对象:
interface MyInterface {
fun foo():Int
}
data class MyClass(val delegate : MyInterface) : MyInterface by delegate
object ImplementationA: MyInterface { override fun foo() = 7 }
object ImplementationB: MyInterface { override fun foo() = 5 }
val objA = MyClass(ImplementationA)
println(objA.foo()) // returns 7
val objB = objA.copy(ImplementationB)
println(objB.foo()) // returns 5
println(objA.foo()) // still 7
希望这仍然有用。