在Groovy @Mixin中'返回此'的类型

时间:2011-08-29 13:36:45

标签: groovy mixins

我有一个mixin类,它将不同类型的功能捆绑在一起,不具备共同的传统。使用@Mixin注释应用混合,因此在编译时处理它。

一些mixin方法返回 this 作为方法调用的结果。问题是 this 是混合类型而不是基类的类型。当我想在应用程序的其余部分中键入时,会抛出ClassCastException,说混合类型不能转换为基类型。

在下面的示例代码中,return this返回AMixin类型的对象,而不是BaseClass类型的Object。

如何让return this返回BaseClass类型的对象而不是AMixin类型的对象?

class AMixin {

  def getWhatIWant(){
    if(isWhatIwant){
      return this
    } else {
      getChildWhatIWant()
    }
  }

  def getChildWhatIWant(){
    for (def child in childred) {
        def whatIWant = child.getWhatIWant()
        if (whatIWant) {
            return whatIWant
        }
    }
    return null
  }
}


@Mixin(AMixin)
class BaseClass {
  boolean isWhatiWant
  List<baseClass> children
}

2 个答案:

答案 0 :(得分:3)

我刚遇到同样的情况。我通过在具体类中将'this'设置为具体类中的私有变量'me'并在Mixin类中返回'me'来解决它。例如:

class MyMixin {
    def mixinMethod() {
        // do stuff
        return me
    }
}

@Mixin(MyMixin)
class MyConcreteClass {
    private MyConcreteClass me
    MyConcreteClass() {
        me = this
    }
}

我觉得它有点笨拙,但我认为它比其他解决方案简单得多。我个人需要能够在多个类中使用相同的Mixin,听起来如果你不能将多个类别分配给单个Mixin类,其他提议的解决方案就不允许这样做。

答案 1 :(得分:2)

我创建了类Base,将类别添加到AMixin类,BaseClass从Base扩展.....(http://groovy.codehaus.org/Category+and+Mixin+transformations

在GroovyConsole中执行此操作我得到了

的BaseClass @ 39c931fb

class Base {
     boolean isWhatIwant
     List<BaseClass> children
}

@Category(Base)
class AMixin {

  def getWhatIWant(){
    if(isWhatIwant){
      return this
    } else {
      getChildWhatIWant()
    }
  }

  def getChildWhatIWant(){
    for (def child in children) {
        def whatIWant = child.getWhatIWant()
        if (whatIWant) {
            return whatIWant
        }
    }
    return null
  }
}


@Mixin(AMixin)
public class BaseClass extends Base {

}

def b = new BaseClass(isWhatIwant:true)
println b.getWhatIWant()

编辑只是一个DummyClass。我知道它的工作非常尴尬....我确信Guillaume Laforge可以回答它是如何工作的......

class DummyClass {

}

@Category(DummyClass)
class AMixin {

  def getWhatIWant(){
    if(isWhatIwant){
      return this
    } else {
      getChildWhatIWant()
    }
  }

  def getChildWhatIWant(){
    for (def child in children) {
        def whatIWant = child.getWhatIWant()
        if (whatIWant) {
            return whatIWant
        }
    }
    return null
  }
}


@Mixin(AMixin)
public class BaseClass extends DummyClass {
     boolean isWhatIwant
     List<BaseClass> children
}

def b = new BaseClass(isWhatIwant:true)
println b.getWhatIWant()