@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()
中的三个属性概述的情况下实现这一点? :最佳答案
我不认为你可以在类里面做到这一点。也许你想要 traits (讨论中 更新: available in Groovy 2.3 并且已经摇摆不定!)或者,对于纯动态解决方案,@Mixin
,你会用一个好的测试套件来支持它。
我的猜测:@Delegate
是你最好的 friend ,但就目前而言,你只能存储 Chest
Container
中的对象类型变量。所以你需要一些接口(interface)。
即使父类(super class)不在你的控制之下,你也可以使用 groovy as
运算符使其实现接口(interface)。
首先,我重写了您的类(class)以删除 abstract
并添加接口(interface):
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
添加并自动继承委托(delegate)的接口(interface):@TC
abstract class Container {
@Delegate Location location = new Location()
@Delegate Entity entity = new Entity()
}
@TC class Chest extends Container { }
最后,只要您坚持接口(interface),它就可以进行类型检查:
@TC class Mult {
static main(args) {
def x // use 'def' for flow-typing
Container c = new Chest() //Chest extends Container
HasMass e = c
x = e.mass
def l = c as HasContent
x = l.content //Programmer error, should throw compile-time error
assert c.content.collect { Entity it -> it.mass } == [10.0, 20.0]
}
}
关于Groovy:有没有办法在使用类型检查的同时实现多重继承?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21448714/