是否有可能取代现有对象的常规方法? [英] Is it possible to replace groovy method for existing object?

查看:80
本文介绍了是否有可能取代现有对象的常规方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码试图替换Groovy类中的现有方法:

The following code tried to replace an existing method in a Groovy class:

class A {
  void abc()  {
     println "original"
  }
} 

x= new A()
x.abc()
A.metaClass.abc={-> println "new" }
x.abc()
A.metaClass.methods.findAll{it.name=="abc"}.each { println "Method $it"}

new A().abc()

结果如下:

original
original
Method org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod@103074e[name: abc params: [] returns: class java.lang.Object owner: class A]
Method public void A.abc()
new

这是否意味着当通过将元类设置为闭包来修改元类时,它并不真正代替它,而只是增加了可调用的另一种方法,从而导致元类有两种方法?是否有可能真正取代该方法,以便第二行输出打印新?

Does this mean that when modify the metaclass by setting it to closure, it doesn't really replace it but just adds another method it can call, thus resulting in metaclass having two methods? Is it possible to truly replace the method so the second line of output prints "new"?

当试图弄清楚时,我发现 DelegatingMetaClass 可能会有所帮助 - 这是最Groovy的方式吗?

When trying to figure it out, I found that DelegatingMetaClass might help - is that the most Groovy way to do this?

推荐答案

您可以使用每个实例的metaClass来更改现有对象中的值,如下所示:

You can use the per-instance metaClass to change the value in the existing object like so:

x= new A()
x.abc()
x.metaClass.abc={-> println "new" }
x.abc()
x.metaClass.methods.findAll{it.name=="abc"}.each { println "Method $it"}

但是正如你所看到的,x将会有两个与之相关的方法(实际上,一个方法和闭包你添加了

But as you have seen, x will have two methods associated with it (well, in actual fact, a method and the closure you added

如果你改变了A的定义,以便方法变成如下所示的闭包定义:

If you change the definition of A so that the method becomes a closure definition like so:

class A {
  def abc = { ->
     println "original"  
  }
} 

然后,您将只会在metaClass中获得单个闭包,并且在更改后不会有方法

Then you will only get a single closure in the metaClass and no method after the alteration

这篇关于是否有可能取代现有对象的常规方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆