如何在Groovy中设置新属性并提供其setter

时间:2015-01-26 01:54:39

标签: groovy closures metaprogramming

我有这个时髦的课程:

class Car {
    int speed = 0
}

我想使用元编程来引入一个新属性" color"并且还将setColor方法提供给 Car 对象的实例,如下所示:

 def c = new Car()

 c.metaClass.setProperty("color", "red")

 c.metaClass.setColor = { 
       def newColor-> "color switched from $existingColor to $newColor
 }

我的最终目标是,当我打电话时:

c.color("yellow")

打印出来:

color switched from red to yellow"

我已经使用上面的代码处理 c.color 部分,但不是第二部分(setColor)。

有人可以帮我解决这个问题,还是告诉我它是否可能?

感谢。

2 个答案:

答案 0 :(得分:2)

添加属性时,您可以免费获得getter和setter,例如

class Car {
    int speed = 0
}
def c = new Car()
c.metaClass.setProperty("color", "red")
assert c.color == 'red'
c.setColor('blue')
assert c.getColor() == 'blue'

如果最终目标是调用名为color的方法来设置color属性,则可以添加如下属性:

c.metaClass.color << { col ->
    println "color switched from $delegate.color to $col"
    c.color = col
}

c.color('yellow') // prints "color switched from blue to yellow"
assert c.color == 'yellow'

答案 1 :(得分:2)

你非常接近它的工作。由于您创建了一个具有setter的新属性,因此您需要做的就是:

 c.metaClass.getColor = {'red'}

 c.metaClass.setColor = { 
       def newColor-> println "color switched from ${delegate.color} to $newColor"
 }

 c.color = "yellow"

请注意,这不是设置的属性,而只是提供了为委托颜色注入get和set方法的机制。

这可能是通过这样做来解决的:

def currentColor = 'red'
def previousColor = '' 
c.metaClass.getColor = { currentColor }
c.metaClass.getPreviousColor = { previousColor }

c.metaClass.setColor = { 
   def newColor-> previousColor = delegate.color; currentColor = newColor
}
c.color = "yellow"
println "Changed color from $c.previousColor to $c.color"
c.color = "blue"
println "Changed color from $c.previousColor to $c.color"

但现在我们的代码纯粹是为了不用于生产的实验:)