我很困惑代表团在科特林的工作方式。 Wikipedia说:
有了语言级的委派支持,这可以通过使委托中的self引用原始(发送)对象而不是委托(接收对象)来隐式完成。
给出以下代码:
interface BaseInterface {
fun print()
}
open class Base() : BaseInterface {
override fun print() { println(this) }
}
class Forwarded() {
private val base = Base()
fun print() { base.print() }
}
class Inherited() : Base() {}
class Delegated(delegate: BaseInterface) : BaseInterface by delegate
fun main(args: Array<String>) {
print("Forwarded: ")
Forwarded().print();
print("Inherited: ")
Inherited().print();
print("Delegated: ")
Delegated(Base()).print();
}
我得到以下输出:
Forwarded: Base@7440e464
Inherited: Inherited@49476842
Delegated: Base@78308db1
我希望Delegated返回Delegated
,因为self / this应该引用原始对象。我会弄错还是科特林斯代表团不同?
答案 0 :(得分:0)
Kotlin delegation非常简单-它生成所有接口方法,并在委托对象上隐式调用它,但用户显式覆盖的方法除外。
您的示例与以下功能相同:
class Delegated(delegate: BaseInterface) : BaseInterface{
// when generating bytecode kotlin assigns delegate object to internal final variable
// that is not visible at compile time
private val d = delegate
override fun print(){
d.print()
}
}
因此,很清楚为什么打印Base
。
答案 1 :(得分:0)
如果我们查看将其反编译成的反编译后的Java字节码,我认为这是最容易理解的
您可以执行以下操作:转到
Tools > Kotlin > Show Kotlin Bytecode
,然后单击Decompile
public final class Delegated implements BaseInterface {
// $FF: synthetic field
private final BaseInterface $$delegate_0;
public Delegated(@NotNull BaseInterface delegate) {
Intrinsics.checkParameterIsNotNull(delegate, "delegate");
super();
this.$$delegate_0 = delegate;
}
public void print() {
this.$$delegate_0.print();
}
}
因此,当您进行接口委托时,会发生的事情是Kotlin为名为$$delegate_0
的委托创建了一个字段,并在您的 delegating 类中添加了将在其上运行的方法。 $$delegate_0
。您也可以有多个代表,他们将获得自己的字段。但是有一个警告:您不能直接访问$$delegate_0
,即使您将其设置为var
也是如此:
class Delegated(var delegate: BaseInterface) : BaseInterface by delegate
它将编译为:
public final class Delegated implements BaseInterface {
@NotNull
private BaseInterface delegate;
// $FF: synthetic field
private final BaseInterface $$delegate_0;
@NotNull
public final BaseInterface getDelegate() {
return this.delegate;
}
public final void setDelegate(@NotNull BaseInterface var1) {
Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
this.delegate = var1;
}
public Delegated(@NotNull BaseInterface delegate) {
Intrinsics.checkParameterIsNotNull(delegate, "delegate");
super();
this.$$delegate_0 = delegate;
this.delegate = delegate;
}
public void print() {
this.$$delegate_0.print();
}
}
可悲。我已经写过有关here的话题。