Groovy's extension-module compared to java's inheritance
Asked Answered
O

3

6

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?

Oxidation answered 26/4, 2015 at 14:51 Comment(1)
Thinking of extension modules in terms of inheritance is a bad idea. They extend a particular class with additional behavior: so they're modifying an existing inheritance hierarchy rather than contributing to it...but their context is really focused on a single class (so again, ignore inheritance). Other languages have a similar construct as part of first class type definition (Go, Scala, Kotlin...). They're static because they're defined outside of their runtime binding environment:, so instead receive the instance as an argument (again similar to the approach of other languages).Shackelford
H
0

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.

Headforemost answered 27/4, 2015 at 17:4 Comment(0)
K
0

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).

Kramlich answered 27/4, 2015 at 17:32 Comment(0)
R
0

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 via use Category methods and metaClass 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 and metaClass extension methods don't get overridden by extension methods on subclasses.
  • Q. Can they call inherited super methods?
    No, since they're implemented via static 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 via static 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.

Rutledge answered 28/4, 2015 at 2:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.