groovy - 动态向groovy中的对象添加属性或方法

标签 groovy monkeypatching

是否可以在 Groovy 中动态向对象添加属性或方法?这是我到目前为止所尝试过的:

class Greet {
  def name
  Greet(who) { name = who[0].toUpperCase() + [1..-1] }
  def salute() { println "Hello $name!" }
}

g = new Greet('world')  // create object
g.salute()              // Output "Hello World!"

g.bye = { println "Goodbye, $name" }
g.bye()

但我得到以下异常:

Hello World!
Caught: groovy.lang.MissingPropertyException: No such property: bye for class: Greet
Possible solutions: name
    at test.run(greet.groovy:11)

最佳答案

如果您只想将 bye() 方法添加到 Greet 类的单个实例 g 中,您需要执行以下操作:

g.metaClass.bye = { println "Goodbye, $name" }
g.bye()

否则,要将 bye() 添加到 Greet 的所有实例(从现在开始),请调用

Greet.metaClass.bye = { println "Goodbye, $name" }

但是您需要在创建 Greet 类的实例之前执行此操作

Here is a page on the per-instance metaClass

And here is the page on MetaClasses in general

<小时/>

此外,您的构造函数中存在错误。您在 [1..-1] 前面缺少 who,并且如果向构造函数传递了少于 2 个字符的 String在长度上,它会抛出异常

更好的版本可能是:

Greet( String who ) { 
  name = who.inject( '' ) { String s, String c ->
    s += s ? c.toLowerCase() : c.toUpperCase()
  }
}
<小时/>

正如评论中提到的,

Greet( String who ) { 
  name = who.capitalize()
}

正确的方法

关于groovy - 动态向groovy中的对象添加属性或方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4781936/

相关文章:

java - 构建后的 Gradle 复制任务

grails - Grails findAll闭包将查询与hasmany字段组​​合在一起

grails - Grails中的一对一关系显示

groovy - 使用 Gradle 创建 Groovy 可执行 JAR

python - 如何猴子补丁Django?

python - 我可以向内置 Python 类型添加自定义方法/属性吗?

grails - 在Grails标记库中使用<<

ruby-on-rails - 覆盖 ruby​​ 类中的 module_function 以访问原始文件

python - Python 中的猴子修补会影响直接导入吗?

javascript - 防止 TypeScript 公共(public)函数调用私有(private)函数