2011-08-29 165 views
2

我有一个mixin类,它为不共享共同遗产的不同类型的功能捆绑在一起。混合是使用@Mixin注释应用的,因此它在编译时处理。Groovy中'return this'的类型@Mixin

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

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

我该如何让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 
} 

回答

3

我只是碰到了这个同样的情况。我通过在具体类中将'this'设置为具体类中的私有变量'me'并在Mixin类中返回'我'来解决此问题。例如:

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

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

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

+0

此解决方案有效,谢谢。由于我的Mixin必须被初始化,所以我选择用这个方法调用这个方法init(this),所以我可以通过这种方式将“真实的”这个传递给Mixin - 对我来说似乎更加清洁。但是,两种解决方法都有不对的地方,它们不应该是必需的。 – Ice09

+0

这种方法解决了我的问题,但是Ice09已经说过这种解决方法并不合适。 – Ruben

2

我创建的类加碱类别的AMixin类和BaseClass的从底部延伸.....(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() 
+0

Mixin类上的@Category(Base)注释有什么影响?我认为这是不可能的,如果我有多个基类,例如BaseA,BaseB和BaseC。 – Ruben

+0

不,你不能在Mixin中有多个类别的基类,但是你可以有多个具有相同类别的mixin,这有助于形成一种“多层次”。 @Category在groovy中用于元编程和扩展类。 – jjchiw

+0

但是我为什么要将BaseClass的AMixin类扩展为Category?我只需要在BaseClass中提供AMixin功能。 – Ruben