1

我写了一个我可以使用的方法ClassName.methodName(args)

我怎样才能做到这一点,以便我可以使用methodName(args).

我尝试像这样猴子修补对象:

class Object {
    def methodName(args) {
        // method definition
    }
}

更新:

我尝试了 dmahapatro 所说的。

import static groovy.json.JsonOutput.*

Object.metaClass.outputJson = {
    return println(prettyPrint(toJson(it)))
}

outputJson([:])

返回:

Caught: groovy.lang.MissingMethodException: No signature of method: Object.outputJson() is applicable for argument types: (java.util.LinkedHashMap) values: [[:]]
Possible solutions: outputJson(), outputJson(java.lang.Object)
groovy.lang.MissingMethodException: No signature of method: Object.outputJson() is applicable for argument types: (java.util.LinkedHashMap) values: [[:]]
Possible solutions: outputJson(), outputJson(java.lang.Object)
    at Object.run(Object.groovy:7)
[Finished in 2.1s]

编辑产生的问题是因为 Object.groovy 与 Groovy 的 Object.java 冲突。一旦我将它重命名为 ObjectMeta (或任何其他不冲突的名称,它就起作用了)。

4

2 回答 2

1

使用ExpandoMetaClass_Object

Object.metaClass.printsHello = {
    return it
}

assert "Hello" == printsHello("Hello")
assert "Hello" == 'ABC'.printsHello("Hello")
assert "Hello" == 123.printsHello("Hello")
assert "Hello" == new Object().printsHello("Hello")

class A{
    Integer a
}

assert "Hello" == new A(a: 10).printsHello("Hello")

这也可以通过使用@Category如下来实现

@Category(Object) class CustomizedObject{
    def printsHello(String str){
        return str
    }
}

String.mixin CustomizedObject
assert 'Hello' == 'ABC'.printsHello('Hello')

Integer.mixin CustomizedObject
assert 'Hello' == 123.printsHello('Hello')

BigInteger.mixin CustomizedObject
assert 'Hello' == 123G.printsHello('Hello')

@Mixin(CustomizedObject) //Compile Time Mixin
class A{
}

assert 'Hello' == new A().printsHello('Hello')

如果您想@Category在 jar 中分发,则将其包含CustomizedObject在该 jar 中并在需要的地方使用它。

import static groovy.json.JsonOutput.*

Object.metaClass.outputJson = {
    return prettyPrint(toJson(it))
}

println outputJson([a: 1, b: 2, c: 3])

//Prints:
{
    "a": 1,
    "b": 2,
    "c": 3
}

注意:-
这里要注意的一件事是,我们直接使用metaClassonObject有时可能很关键,metaClass一旦完成,您应该清除 from 对象。

于 2013-06-17T19:05:12.000 回答
0

您可以做多种可能性。最简单的一种是使用类别。在您的主要方法或脚本中执行以下操作:

use(ObjectExtender) {
  startProgram();
}

然后像这样创建 ObjectExtender 类:

class ObjectExtender {
  static def methodName(Object self, Map args) {
    ...
  }
}

只要您在use调用的控制流中,就可以调用methodName任何对象。还有其他可能性,比如为对象创建一个新的元类,但我可能会选择类别。

于 2013-06-17T18:57:29.603 回答