Groovy 将方法添加到接口元类只能工作一次
因此,将方法添加到接口元类会将其添加到接口实现的每个实例中,但只添加一次。每次将该方法添加到每个实现类都会起作用,这是一个变化 在重新分配方法之间清理元类似乎不会改变任何东西 以下是一个可运行的示例:Groovy 将方法添加到接口元类只能工作一次,groovy,metaprogramming,Groovy,Metaprogramming,因此,将方法添加到接口元类会将其添加到接口实现的每个实例中,但只添加一次。每次将该方法添加到每个实现类都会起作用,这是一个变化 在重新分配方法之间清理元类似乎不会改变任何东西 以下是一个可运行的示例: interface X {} class A implements X {} class B implements X {} X.metaClass.test = { println "v1" } new A().test() new B().test() X.metaClass.test =
interface X {}
class A implements X {}
class B implements X {}
X.metaClass.test = { println "v1" }
new A().test()
new B().test()
X.metaClass.test = { println "v2" }
new A().test()
new B().test()
A.metaClass.test = { println "v3" }
B.metaClass.test = { println "v3" }
new A().test()
new B().test()
A.metaClass.test = { println "v4" }
B.metaClass.test = { println "v4" }
new A().test()
new B().test()
结果是:
v1
v1
v1
v1
v3
v3
v4
v4
这是故意的行为吗?如果是,为什么?还是一个bug?哇,我认为这实际上可能是一个长期未解决的bug()。问题似乎在于,一旦在接口中声明了方法,就不能通过元类重写它。此限制不适用于类 因此,我猜是您第一次通过元类声明该方法时,它被正确初始化,因为它以前不存在。但是对接口元类方法的任何后续更新都不起作用,因为它已经存在。由于这个bug不适用于类元类,所以类元类的更改是有效的 记录单中列出的解决方法似乎与您找到的类似;即,更新接口和类上的元类:
您是否期待
v2
?在接口中,如何声明相同的方法?一旦正确?输出是预期的;您的期望是什么?没错,我希望在X
接口上重写test
方法会调用它来使用重写的行为,即打印“v2”字符串。对不起,我不太明白你反问句的明显性。当我做类似于元类.someMethod的事情时,我希望我不是真的两次声明同一个方法,而是重写前面的声明。有没有其他方法可以做到这一点?另外,如果将“metaClass.someMethod”解释为“两次声明相同的方法”,而不是重写以前的实现(在目标类上执行相同的操作时似乎会解释),我希望会出现某种异常。哇,感谢找到错误,我也在寻找,但失败了。长时间语言特性中的bug并不是一个理智的开发人员所期望的,所以知道它确实是这样是很好的,而不是我对它应该如何工作缺乏理解。然后。。。8年,很好!这一个比提供的门更老练,仍然没有解决!我会把赏金再留几天,也许它会引起更多的关注。
interface X {}
class A implements X {}
class B implements X {}
X.metaClass.test = { println "v1" }
new A().test()
new B().test()
X.metaClass.test = { println "v2" }
A.metaClass.test = { println "v2" }
new A().test() // Will print "v2"
new B().test() // Will print "v1" still