与java的继承相比,Groovy的扩展模块

时间:2015-04-26 14:51:31

标签: java groovy gdk extension-modules

groovy的扩展模块是java的继承功能的混合形式吗?为什么扩展模块需要声明为静态?

3 个答案:

答案 0 :(得分:0)

简短的回答是我认为是的。由于扩展方法的继承完全由运行时(和静态编译器)完成,因此有点难以清楚地回答。因此,它与Java如何继承无关。

回答第二个问题......它们是静态的,因为在你需要状态的情况下,你通常使用元类。扩展方法最初被认为是方便方法或使API更加Groovy。因此,它们是添加到元类的一种特殊形式的方法。您可以将它们视为简化版本。但这也意味着他们没有所有的能力。实现扩展方法,可以将本地状态保持在每个" - 对象的基础上(基本上是什么字段/属性)实际上很难有效...但是你总是可以使用每个实例的元类对此。

答案 1 :(得分:0)

对于所有广泛的目的,它们是语法糖,因此静态方法似乎更像OOP。没有继承,因为Java和Groovy中的静态方法不参与继承(即类不继承静态方法)。

这些方法需要是静态的,因为编译器不知道如何实例化扩展方法的周围类。

但是我相信有些语言允许在封闭类之外定义方法并进行某种类型的继承但不是很多(我相信CLOS和Dylan都这样做)。它们也是许多语言,似乎允许添加方法但是#34;对象的类型"实际上已更改/隐藏到其他类型。这称为adhoc多态(例如Clojure,Haskell,Golang和Scala),但与包含多态(Java继承)无关。

答案 2 :(得分:0)

不幸的是reference documentation和其他文档没有定义扩展方法的语义:

  • Q值。他们可以覆盖实例方法吗? 我通过use类别方法和metaClass expando方法测试了扩展方法。这两种方法都不会覆盖实例方法。我没有通过extension modules测试module descriptor
  • Q值。是否可以通过子类的扩展方法覆盖它们? 我也测试过了。 use方法和metaClass扩展方法不会被子类的扩展方法覆盖。
  • Q值。他们可以称为继承的super方法吗? 不,因为它们是通过static方法实现的。
  • Q值。他们可以称私人方法吗? 实验表明,他们可以令人惊讶。
  • Q值。他们可以访问私有实例变量吗? 不,因为它们是通过static方法实现的。
  • Q值。它们是否可以从Java方法中调用? 编译调用代码时,可能if the extension module is on the classpath。我没有测试过。

结论: 扩展方法不是一种继承形式。它们似乎是Universal Function Call Syntax (UFCS)的动态形式,也就是说,语言可以&# 39;找到一个方法variable.foo(arguments),它查找要调用的静态扩展函数foo(variable, arguments)。 [如果错误,请纠正我的假设!]

您问他们为什么被定义为static。这似乎与语义相匹配:静态函数不参与继承,尽管它的调用语法使它看起来像一个方便的方法调用。

您可以使用@groovy.lang.Category注释编写类似实例方法的扩展方法。这会在编译时进行AST转换,将其转换为合适的静态方法。

另见Groovy traits 是(mixin)继承的一种形式。