我有一个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
}
答案 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()