Is groovy's extension module feature a hybrid form of java's inheritance feature? Why are the extension-module needs to be declared as static?
Short answer is I think yes. It is a bit difficult to answer clearly, since the inheritance for the extension methods is done completely by the runtime (and the static compiler). As such it has nothing to do with how Java does inheritance.
To answer the second question... They are static, because for situations in which you need state you usually use the meta class. Extension methods are initially thought of as convenience methods or to make the API more Groovy. As such, they are a special form of methods added to the meta class. You can see them as simplified version. But that also means they don't have all the abilities. Implementing extension methods, that can keep local state on a per "self"-object basis (basically what fields/properties would do) is actually difficult to do efficient... but you could always use per instance meta classes for this.
For all extensive purposes they are syntactic sugar so that a static method appears to be more OOP like. There is no inheritance because static methods in Java and Groovy do not participate in inheritance (that is classes do not inherit static methods).
The methods need to be static because the compiler does not know how to instantiate the surrounding class of the extension method.
However I believe there are languages that do allow for methods to be defined outside of the enclosing class and do some sort inheritance but not many do not (I believe CLOS and Dylan do). Also they are many languages that appear to allow methods to be added but the type of "object" is actually changed/hidden to some other type. This is called adhoc polymorphism (e.g. Clojure, Haskell, sort of Golang and sort of Scala) but again has nothing to do with inclusional polymorphism (Java inheritance).
Unfortunately the reference documentation and other docs don't define the semantics of extension methods:
- Q. Can they override instance methods?
I tested extension methods viause
Category methods andmetaClass
expando methods. Neither approach overrides instance methods. I didn't test extension modules installed via module descriptor. - Q. Can they be overridden by extension methods on subclasses?
I tested that, too.use
methods andmetaClass
extension methods don't get overridden by extension methods on subclasses. - Q. Can they call inherited
super
methods?
No, since they're implemented viastatic
methods. - Q. Can they call private methods?
Experiments showed that they can, surprisingly. - Q. Can they access private instance variables?
No, since they're implemented viastatic
methods. - Q. Are they callable from Java methods?
Maybe, if the extension module is on the classpath when compiling the calling code. I didn't test it.
Conclusion: Extension methods are not a form of inheritance. They seem to be a dynamic form of Universal Function Call Syntax (UFCS), that is, when the language can't find a method variable.foo(arguments)
it looks for a static extension function foo(variable, arguments)
to call. [Please correct my hypothesis if wrong!]
You asked why they're defined as static
. That seems to match the semantics: A static function that's not involved in inheritance, although its calling syntax makes it look like a convenient method call.
You can write an extension method like an instance method using the @groovy.lang.Category annotation. That does AST transformations at compile time to turn it into a suitable static method.
Also see Groovy traits. That is a form of (mixin) inheritance.
© 2022 - 2024 — McMap. All rights reserved.