Kotlin:将复合类属性公开为公共主机类属性
假设我们有一个Kotlin:将复合类属性公开为公共主机类属性,kotlin,properties,composition,class-design,Kotlin,Properties,Composition,Class Design,假设我们有一个Composite类 class Composite(val one: Int, val two: Int) class Host(val comp: Composite) 和一个主机类 class Composite(val one: Int, val two: Int) class Host(val comp: Composite) 现在我们可以打印复合对象的属性了 fun hostTest() { val comp = Composite(2, 3)
Composite
类
class Composite(val one: Int, val two: Int)
class Host(val comp: Composite)
和一个主机
类
class Composite(val one: Int, val two: Int)
class Host(val comp: Composite)
现在我们可以打印复合对象的属性了
fun hostTest() {
val comp = Composite(2, 3)
val hst = Host(comp)
println(hst.comp.one)
println(hst.comp.one)
}
在Kotlin中,是否可以将复合
属性公开为主机
类的直接属性?
所以,我想写这样的东西:
fun hostTest() {
val comp = Composite(2, 3)
val hst = Host(comp)
println(hst.one)
println(hst.one)
}
当然,可以在主机中创建代理属性,但我希望Kotlin作为一种实用语言能够直接支持这一点。这不可能直接实现,但您可以通过来模拟它,这要求您将复合
的属性移动到一个接口:
interface Composite {
val one: Int
val two: Int
}
class CompositeImpl(
override val one: Int,
override val two: Int
) : Composite
class Host(val comp: Composite) : Composite by comp
如果需要,您可以将comp
属性private
,也可以使用Composite
在Composite by…
子句中主机初始化时可用的任何其他Composite
实例,甚至在适当的位置构建一些复合材料。Kotlin的解决方案是
你可以用多种方式来做,这取决于你的需要,你应该选择哪一种。首先,您需要为您的组合
提供一个界面
:
interface Composite {
val one: Int
val two: Int
}
class CompositeWithDefaults(override val one: Int = 1,
override val two: Int = 2) : Composite
和默认实现:
class DefaultComposite(override val one: Int,
override val two: Int) : Composite
然后,您可以使用by
关键字从Host
委托给Composite
的实例:
class Host(val composite: Composite) : Composite by composite
class Host(one: Int, two: Int) : Composite by DefaultComposite(one, two)
如果您有合理的组合的默认值
:
interface Composite {
val one: Int
val two: Int
}
class CompositeWithDefaults(override val one: Int = 1,
override val two: Int = 2) : Composite
然后,您甚至不必将复合
作为构造函数参数传递:
class Host() : Composite by CompositeWithDefaults()
或者,您可以将其字段传递到主机
:
class Host(val composite: Composite) : Composite by composite
class Host(one: Int, two: Int) : Composite by DefaultComposite(one, two)
或具有默认值:
class Host(composite: Composite = CompositeWithDefaults()) : Composite by composite
但是要小心:您不应该委托给可变的属性,因为使用by
生成的字节码将为您的委托使用一个内部字段,并且替换原始对象将无效。我已经写过了
如果composite
是var
,则生成的Java代码就是这样的:
public final class Host implements Composite {
@NotNull
private Composite composite;
// $FF: synthetic field
private final Composite $$delegate_0;
@NotNull
public final Composite getComposite() {
return this.composite;
}
public final void setComposite(@NotNull Composite var1) {
Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
this.composite = var1;
}
public Host(@NotNull Composite composite) {
Intrinsics.checkParameterIsNotNull(composite, "composite");
super();
this.$$delegate_0 = composite;
this.composite = composite;
}
public int getOne() {
return this.$$delegate_0.getOne();
}
public int getTwo() {
return this.$$delegate_0.getTwo();
}
}
公共最终类主机实现复合{
@NotNull
私人复合材料;
//$FF:合成场地
私有最终复合$$delegate\u 0;
@NotNull
公共最终复合getComposite(){
返回此.composite;
}
公共最终void setComposite(@NotNull Composite var1){
Intrinsics.checkParametersNotNull(var1,“”);
this.composite=var1;
}
公共主机(@NotNull复合){
本质。检查参数完整(复合,“复合”);
超级();
此$$delegate_0=复合;
这个。复合=复合;
}
公共整数getOne(){
返回此值。$$delegate_0.getOne();
}
公共int getTwo(){
返回此值。$$delegate_0.getTwo();
}
}
请注意,setter并没有设置$$delegate\u 0
,而是设置composite
Thx,这正是我所需要的,因为我的composite是一个第三方类,有很多属性需要打包。很抱歉,我告诉你,你的第二个链接已经死了。