@groovy.transform.TypeChecked
abstract class Entity {
...
double getMass() {
...
}
...
}
@groovy.transform.TypeChecked
abstract class Location {
...
Entity[] getContent() {
...
}
...
}
@groovy.transform.TypeChecked
abstract class Container {...} //inherits, somehow, from both Location and Entity
@groovy.transform.TypeChecked
class Main {
void main() {
double x
Container c = new Chest() //Chest extends Container
Entity e = c
x = e.mass
Location l = c
x = l.content //Programmer error, should throw compile-time error
}
}
基本上,有没有办法实现这一点,而不会牺牲main()
中的三个属性轮廓中的任何一个:
答案 0 :(得分:6)
我认为你不能用课程做到这一点。也许你想要traits(正在讨论 更新: available in Groovy 2.3并且已经摇摆不定!)或者,对于纯粹的动态解决方案,{{1你用一个好的测试套件备份它。
我猜:@Mixin
是你最好的朋友,但是,就目前而言,你只能在@Delegate
类型变量中存储Chest
个对象。所以你需要一些接口。
即使超类不受你的控制,你也可以使用groovy Container
运算符来实现一个接口。
首先,我重写了你的类以删除as
并添加接口:
abstract
注意我没有将import groovy.transform.TypeChecked as TC
interface HasMass { double mass }
interface HasContent { Entity[] getContent() }
@TC class Entity implements HasMass { double mass }
@TC class Location {
Entity[] getContent() {
[new Entity(mass: 10.0), new Entity(mass: 20.0)] as Entity[]
}
}
添加到HasContent
,以显示Location
的使用情况。
其次,来自as
和Container
。添加了Chest
并自动继承了委托的接口:
@Delegate
最后,只要您坚持使用接口,它就可以进行类型检查:
@TC
abstract class Container {
@Delegate Location location = new Location()
@Delegate Entity entity = new Entity()
}
@TC class Chest extends Container { }