简体   繁体   中英

In which sequence does method call work in groovy?

I am using groovy 2.3.8

I am trying to figure out how method calls work in groovy. Specifically if we have a Java class hierarchy each having a metaClass like below

class A {
}
A.metaClass.hello = {
  "hello superclass"
}

class B extends A {
}
B.metaClass.hello = {
  "hello subclass"
}

If I use new B().hello() I get hello subclass . If I remove meta class of B then I get hello superclass .

Based on changing the above example I think groovy goes in the below sequence to find which method to call

method-in-subclass's-metaclass ?: subclass-metho  ?: method-in-superclass's metaclass ?: method-in-superclass

So how does groovy lookup which method to call?

Well, the hierarchy is the expected object oriented programming method overloading, which is what you witnessed. What differs is the dispatching. Instead of starting with a method lookup in instance's class, it begins with the MOP (meta object protocol).

In layman's terms, because the MOP is programmable, so is the way methods are invoked :)

How it works

The following diagram from Groovy's documentation shows how methods are looked up.

Groovy对象的Groovy方法分派

What's not clear in the diagram is that there's an instance metaclass as well, and it comes before the class's metaclass.

Something that may help is looking at an object's or class's .metaClass.methods Methods added through inheritance, traits, metaclass, etc are listed in a flat list. The inheritance hierarchy is flattened. .metaClass.metaMethods on the other hand seems to contain methods added via the GDK. From the list I could not tell method precedence :(

Based on observation, the rule seems to be this: the last MetaClass standing wins.

class A { }

class B extends A { }

A.metaClass.hello = {
  "hello superclass"
}

B.metaClass.hello = {
  "hello subclass"
}

def b = new B()

assert b.hello() ==  "hello subclass"
b.metaClass = A.metaClass
assert b.hello() ==  "hello superclass"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM