Groovy元编程添加方法在子类中不可访问

时间:2015-09-02 15:28:39

标签: inheritance groovy metaprogramming

我有以下类来扩展Object类,但是这里添加的方法不能被任何Object的子类访问。是否有解决方法或Groovy元编程限制/限制?

package groovy.runtime.metaclass.java.lang;

class ObjectMetaClass extends DelegatingMetaClass {
    static {
        Object.metaClass.enableGlobally();
    }

    ObjectMetaClass(MetaClass meta) {
        super(meta);
        meta.enableGlobally();
    }

    Object invokeMethod(Object object,
                        String method,
                        Object[] arguments) {
        if (method == 'bar') {
            bar(*arguments);
        } else {
            super.invokeMethod object, method, arguments
        }
    }

    Object bar(config, app) {
        println("... ObjectMetaClass.bar(${config}, ${app})");
    }
}
测试脚本中的

o = new Object();
o.bar("profile.properties", "meta-app"); // works

1.bar("profile.properties", "integer-app"); // does not works
"aString".bar("profile.properties", "string-app"); // does not works

1 个答案:

答案 0 :(得分:2)

您至少有几个选项:ExpandoMetaClassCategories

使用ExpandoMetaClass

Object.metaClass.bar = {config, app ->
    "... Object.bar(${config}, ${app})"
}

o = new Object();

assert o.bar("profile.properties", "meta-app") == '... Object.bar(profile.properties, meta-app)'
assert 1.bar("profile.properties", "integer-app") == '... Object.bar(profile.properties, integer-app)'
assert "aString".bar("profile.properties", "string-app") == '... Object.bar(profile.properties, string-app)'

使用类别

class BarCategory {
    static Object bar(Object self, config, app) {
        "... Object.bar(${config}, ${app})"
    }
}

use(BarCategory) {
    o = new Object();

    assert o.bar("profile.properties", "meta-app") == '... Object.bar(profile.properties, meta-app)'
    assert 1.bar("profile.properties", "integer-app") == '... Object.bar(profile.properties, integer-app)'
    assert "aString".bar("profile.properties", "string-app") == '... Object.bar(profile.properties, string-app)'
}

o = new Object();

try {
    o.bar("profile.properties", "meta-app")
    assert false, 'You should not see this'
} catch (MissingMethodException) {}

try {
    1.bar("profile.properties", "integer-app")
    assert false, 'You should not see this'
} catch (MissingMethodException) {}

try {
   "aString".bar("profile.properties", "string-app")
    assert false, 'You should not see this'
} catch (MissingMethodException) {}

使用类别,您可以控制bar()方法的范围。