【问题标题】:groovy metaclass replace superclass methodgroovy 元类替换超类方法
【发布时间】: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!
 */

【问题讨论】:

    标签: groovy metaprogramming metaclass


    【解决方案1】:

    由于twodoIt 在同一个类中声明,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 为闭包而不是方法,但我更愿意将其声明为方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-08
    • 2012-03-24
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 2011-11-25
    相关资源
    最近更新 更多