我想为一个属性创建一个“重载”设置器,并希望保留该特征。然后,实现该特性的所有子类都将使用其自己的getter,但使用该特性的setter。我不想向现有属性添加任何额外的注释。这是一个澄清:
trait Tr {
abstract String getS()
void setS(String value) {
((GroovyObject) this).setProperty('s', value)
reloadOnSChange()
}
void reloadOnSChange() {
// do something when S is changed
}
}
class Cl implements Tr {
String s
}
Cl cl = new Cl()
cl.s = 'hello world' // reloadOnSChange should be called
这样的属性侦听器可能吗?
答案 0 :(得分:1)
如果要为此使用特征,则必须与实现void getS(String value)
方法不同,因为Groovy编译器会生成Cl.getS(String value)
方法,该方法会遮盖以Tr
特征实现的方法
或者,您的特征可以提供void setProperty(String name, Object value)
方法的实现,如果对属性s
进行了调用,它将执行reloadOnSChange()
方法。考虑以下示例:
trait Tr {
abstract String getS()
abstract void setS(String s)
void reloadOnSChange() {
// do something when S is changed
println "RELOAD"
}
void setProperty(String name, Object value) {
metaClass.setProperty(this, name, value)
if (name == 's') {
reloadOnSChange()
}
}
}
class Cl implements Tr {
String s
}
Cl cl = new Cl()
cl.s = 'hello world'
println "Dump: ${cl.dump()}"
输出:
RELOAD
Dump: <Cl@6580cfdd s=hello world>
主要缺点是,此setProperty
方法将为每个属性执行,因此可能会产生一些开销。在某个时候,JIT应该优化代码,并确保仅在属性名称等于if
时才执行此s
语句。