为什么在Groovy(版本2.4.5)中调用super会错过父类?

Bim*_*hah 9 groovy

鉴于以下类别的安排:

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" 
    } 
}
Run Code Online (Sandbox Code Playgroud)

然后以这种方式使用它们:

iv = new ChildInitAndVisit()
println "ChildInitAndVisit - calling init() -> ${iv.init()}"
println "ChildInitAndVisit - calling visit() -> ${iv.visit()}"

v = new ChildVisitOnly()
println "ChildVisitOnly - calling visit() -> ${v.visit()}"
Run Code Online (Sandbox Code Playgroud)

我希望看到:

ChildVisitOnly - calling visit() -> GrandParent init, Parent init, Child visit
Run Code Online (Sandbox Code Playgroud)

作为最后一个println的输出.相反,我看到:

ChildVisitOnly - calling visit() -> GrandParent init, Child visit
Run Code Online (Sandbox Code Playgroud)

这与ChildInitAndVisit类的行为形成对比,并且与旧版Groovy下的行为不同 - 我检查了2.3.4.

这是一个Groovy错误吗?或者我应该做些不同的事情?

dma*_*tro 1

我相信这是Groovy 的多方法(运行时/动态调度)行为。在运行时,使用init()from而不是from 。GrandParentinit()Parent

以 Java 方式(编译时分派)使用它的一种方法是@CompileStaticChildVisitOnly类上使用。

@CompileStatic
class ChildVisitOnly extends Parent { 

    String visit() { 
        return super.init() + "Child visit" 
    } 
}
Run Code Online (Sandbox Code Playgroud)

上面将给出您期望的结果。

另一种方法是显式使用init()or this.init()inChildVisitOnly而不是@CompileStatic强制使用init()from Parent

class ChildVisitOnly extends Parent { 

    String visit() { 
        return init() + "Child visit" 
    } 
}
Run Code Online (Sandbox Code Playgroud)

这显然偏离了 Groovy 2.3.4 的行为,但我还没有找到关注这种差异的相关问题。我很好奇是否有其他人可以指出导致行为改变的缺陷。:)