Inheritance Groovy中函数重写和可选参数的奇怪行为

Inheritance Groovy中函数重写和可选参数的奇怪行为,inheritance,groovy,optional-parameters,optional-arguments,Inheritance,Groovy,Optional Parameters,Optional Arguments,最好用一点代码来解释这种行为。在本例中,从类y调用super.doSomething(t)而不使用可选参数会导致它递归调用自身(y.doSomething)。这是一个bug,还是有一个解释,为什么不使用可选参数而调用super会导致递归调用 您可以在这里尝试: 下面的代码基本上是为您所拥有的生成的代码,这种表示应该有助于理解它: class X { void doSomething(Integer x) { // remember that for an instance

最好用一点代码来解释这种行为。在本例中,从类
y
调用
super.doSomething(t)
而不使用可选参数会导致它递归调用自身(
y.doSomething
)。这是一个bug,还是有一个解释,为什么不使用可选参数而调用super会导致递归调用

您可以在这里尝试:


下面的代码基本上是为您所拥有的生成的代码,这种表示应该有助于理解它:

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

您指的是什么?默认参数的工作方式是编译器生成重载方法,如我的代码示例中所示。尽管考虑到生成的Java代码,这种行为完全有意义,但在我看来,这种行为似乎是一个bug。尽管可能无法修复,因为这种行为实际上是大多数情况下您所期望的。@Renato“这种行为在我看来像个bug”——它不是bug。生成的代码与默认参数的文档化和预期工作方式一致,并且运行时调度与多态调度在Groovy和Java中的工作方式一致。澄清一下,我的意思是,该行为不是语言或运行时中的错误。编写的代码就是bug存在的地方。我没有说它是bug,但它“看起来”像bug。我想我的想法和OP一样,大多数开发人员可能也会这么想。
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)
    }
}