Groovy 中函数覆盖和可选参数的奇怪行为
Strange behavior with function overriding and optional params in Groovy
最好用一些代码来解释该行为。在此示例中,从 class y
调用 super.doSomething(t)
而没有可选参数会导致它递归调用自身 (y.doSomething
)。这是一个错误还是有解释为什么放弃可选参数并调用 super 导致递归调用。
您可以在这里尝试:https://tio.run/#groovy
class x {
void doSomething(Integer x, Boolean n=false){
println("Super ${n}")
}
}
class y extends x {
@Override
void doSomething(Integer t, Boolean q=true){
println("Sub")
super.doSomething(t) //Stack overflow - super.doSomething calls the subclass
super.doSomething(t, q) //Works as expected
}
}
new y().doSomething(4)
下面的代码基本上是为您所拥有的生成的代码,这种表示应该有助于理解它:
class X {
void doSomething(Integer x) {
// remember that for an instance of Y, this is
// going to call doSomething(Integer, Boolean) in
// the subclass (Y), not this class (X).
doSomething x, false
}
void doSomething(Integer x, Boolean n) {
println("Super ${n}")
}
}
class Y extends X {
void doSomething(Integer t) {
doSomething t, true
}
@Override
void doSomething(Integer t, Boolean q){
println("Sub")
// stack overflow because this calls doSomething(Integer) in
// the parent class which is going to call
// doSomething(Integer, Boolean), which will end up right back here
super.doSomething(t)
// no stack overflow
super.doSomething(t, q)
}
}
最好用一些代码来解释该行为。在此示例中,从 class y
调用 super.doSomething(t)
而没有可选参数会导致它递归调用自身 (y.doSomething
)。这是一个错误还是有解释为什么放弃可选参数并调用 super 导致递归调用。
您可以在这里尝试:https://tio.run/#groovy
class x {
void doSomething(Integer x, Boolean n=false){
println("Super ${n}")
}
}
class y extends x {
@Override
void doSomething(Integer t, Boolean q=true){
println("Sub")
super.doSomething(t) //Stack overflow - super.doSomething calls the subclass
super.doSomething(t, q) //Works as expected
}
}
new y().doSomething(4)
下面的代码基本上是为您所拥有的生成的代码,这种表示应该有助于理解它:
class X {
void doSomething(Integer x) {
// remember that for an instance of Y, this is
// going to call doSomething(Integer, Boolean) in
// the subclass (Y), not this class (X).
doSomething x, false
}
void doSomething(Integer x, Boolean n) {
println("Super ${n}")
}
}
class Y extends X {
void doSomething(Integer t) {
doSomething t, true
}
@Override
void doSomething(Integer t, Boolean q){
println("Sub")
// stack overflow because this calls doSomething(Integer) in
// the parent class which is going to call
// doSomething(Integer, Boolean), which will end up right back here
super.doSomething(t)
// no stack overflow
super.doSomething(t, q)
}
}