鉴于以下类别的安排:
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错误吗?或者我应该做些不同的事情?
我相信这是Groovy 的多方法(运行时/动态调度)行为。在运行时,使用init()
from而不是from 。GrandParent
init()
Parent
以 Java 方式(编译时分派)使用它的一种方法是@CompileStatic
在ChildVisitOnly
类上使用。
@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 的行为,但我还没有找到关注这种差异的相关问题。我很好奇是否有其他人可以指出导致行为改变的缺陷。:)
归档时间: |
|
查看次数: |
390 次 |
最近记录: |