Given the following arrangement of classes:
class GrandParent {
String init() {
return "GrandParent init, "
}
}
class Parent extends GrandParent {
String init() {
return super.init() + "Parent init, "
}
}
class ChildInitAndVisit extends Parent {
String init() {
return super.init() + "Child init"
}
String visit() {
return super.init() + "Child visit"
}
}
class ChildVisitOnly extends Parent {
String visit() {
return super.init() + "Child visit"
}
}
and then using them in this way:
iv = new ChildInitAndVisit()
println "ChildInitAndVisit - calling init() -> ${iv.init()}"
println "ChildInitAndVisit - calling visit() -> ${iv.visit()}"
v = new ChildVisitOnly()
println "ChildVisitOnly - calling visit() -> ${v.visit()}"
I would expect to see:
ChildVisitOnly - calling visit() -> GrandParent init, Parent init, Child visit
as the output of the last println. Instead I see:
ChildVisitOnly - calling visit() -> GrandParent init, Child visit
This is in contrast to the behaviour of the ChildInitAndVisit class and different to the behaviour under older versions of Groovy - I checked 2.3.4.
Is this a Groovy bug? Or should I be doing something different?
In my opinion it is a bug. super.init()
in ChildVisitOnly must call Parent#init().
I believe this is multi-methods (runtime/dynamic dispatch) behavior of Groovy. At runtime, init()
from GrandParent
is used instead of init()
from Parent
.
One way to use it the Java way (compile time dispatch) is to use @CompileStatic
on ChildVisitOnly
class.
@CompileStatic
class ChildVisitOnly extends Parent {
String visit() {
return super.init() + "Child visit"
}
}
Above would give the result you expect.
Another approach would be to use init()
or this.init()
in ChildVisitOnly
explicitly instead of @CompileStatic
to force the use of init()
from Parent
.
class ChildVisitOnly extends Parent {
String visit() {
return init() + "Child visit"
}
}
This obviously deviates from the behavior from Groovy 2.3.4 but I am yet to find a related issue which focuses on this difference. I am curious to see if anybody else can point me to a defect due to which the behavior changed. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With