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