groovy中的方法重载
我试图利用groovy脚本语法的便利性来分配属性,但在特定情况下遇到了问题。我一定错过了一些简单的东西。我将A类、B类和C类定义为:groovy中的方法重载,groovy,overloading,Groovy,Overloading,我试图利用groovy脚本语法的便利性来分配属性,但在特定情况下遇到了问题。我一定错过了一些简单的东西。我将A类、B类和C类定义为: class A { A() { println "Constructed class A!" } } class B { B() { println "Constructed class B!" } } class C { private member C() {
class A {
A() {
println "Constructed class A!"
}
}
class B {
B() {
println "Constructed class B!"
}
}
class C {
private member
C() {
println "Constructed class C!"
}
def setMember(A a) {
println "Called setMember(A)!"
member = a
}
def setMember(B b) {
println "Called setMember(B)!"
member = b
}
}
然后在脚本中尝试以下调用:
c = new C()
c.setMember(new A()) // works
c.member = new A() // works
c.setMember(new B()) // works
c.member = new B() // doesn't work!
最后一个赋值导致错误:“无法将类B的对象强制转换为类A。”“。为什么它不能像调用类A那样为类B调用适当的setMember方法?使用点表示法调用属性的setter方法的快捷方式不进行类型检查。相反,它似乎使用具有给定名称的方法列表中的第一个条目并调用它 您还可以阅读关于Groovy属性处理缺点的扩展评论 如果要绕过此(mis)行为,必须直接调用setter,因为Groovy支持方法调用的类型检查。或者,也可以不使用setter直接访问字段
c.@member=new B()
或者,您可以使用单个setter方法自己进行类型检查:
def setMember(def param) {
if (param instanceof A) println "Called setMember(A)!"
if (param instanceof B) println "Called setMember(B)!"
member = param
}
克里斯托夫的回答是正确的,但正确的方法是不要这样做!为不同的参数类型创建不同的方法,或者让这些类型实现一个公共接口。方法重载在最好的情况下是邪恶的,但对于Groovy更松散的类型,它是彻头彻尾的邪恶。