groovy 元类替换超类方法
Posted
技术标签:
【中文标题】groovy 元类替换超类方法【英文标题】:groovy metaclass replace superclass method 【发布时间】:2012-05-16 01:11:31 【问题描述】:有没有办法使用超类的方法来替换元类对象。 示例:
class A
def doIt()
two()
println 'do it!'
protected two()
println 'two'
class B extends A
def doLast()
doIt()
B b = new B();
b.doIt()
/*
* two
* doit!
*/
b.metaClass.two =
println 'my new two!'
b.doIt();
/*
* my new two!
* do it!
*/
【问题讨论】:
【参考方案1】:由于two
和doIt
在同一个类中声明,groovy 将跳过此调用的元对象协议。您可以通过将超类标记为GroovyInterceptable
来覆盖此行为,这会强制all 方法调用通过invokeMethod
。例如:
class A implements GroovyInterceptable
def doIt()
two()
println 'do it!'
protected two()
println 'two'
class B extends A
def doLast()
doIt()
B b = new B()
b.doIt() // prints two
b.metaClass.two =
println 'my new two!'
b.doIt() // prints my new two!
【讨论】:
嗯好的...问题是我希望这种行为仅用于 grails 应用程序中的单元测试...有没有办法在不使 A 类实现 GroovyInterceptable 的情况下做同样的事情? 另一种方法是让 B 覆盖doIt
并调用 two
本身。或者创建一个 B 的测试特定子类,用标准多态性而不是元类覆盖 two
。
mmm 对不起,这个例子和我的情况不一样......我有一个类 BaseService 使用方法 'getFileOutputStream' 检索文件输出流并创建一个文件,在测试期间我想覆盖它并执行一个返回 ByteArrayOutputStream 的存根方法......所以我有一个调用 two 本身的子类(B),现在我已经将它声明为 two 为闭包而不是方法,但我更愿意将其声明为方法以上是关于groovy 元类替换超类方法的主要内容,如果未能解决你的问题,请参考以下文章