加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Groovy:有没有办法在使用类型检查时实现多重继承?

发布时间:2020-12-14 16:24:05 所属栏目:大数据 来源:网络整理
导读:@groovy.transform.TypeCheckedabstract class Entity { ... double getMass() { ... } ...}@groovy.transform.TypeCheckedabstract class Location { ... Entity[] getContent() { ... } ...}@groovy.transform.TypeCheckedabstract class Container {...}
@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()中的三个属性轮廓中的任何一个:

>直接访问字段,甚至虚拟字段
>分配给两个超类
> Typechecking(编译时)

解决方法

我不认为你可以用课程做到这一点.也许你想要 traits(在讨论更新: available in Groovy 2.3并且已经摇摆不定!)或者,对于一个纯粹的动态解决方案,@ Mixin,你需要备份一个好的测试套件.

我猜:@Delegate是你最好的朋友,但是,就目前而言,你只能将一个Chest对象存储在Container类型变量中.所以你需要一些接口.

即使超类不在您的控制之下,您也可以使用groovy作为运算符来实现接口.

首先,我重写了你的类以删除抽象和添加接口:

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的用法.

第二,来到集装箱和箱子.添加@Delegate并自动继承委托的接口:

@TC 
abstract class Container {
  @Delegate Location location = new Location()
  @Delegate Entity entity = new Entity()
}


@TC class Chest extends Container { }

最后,只要您坚持使用接口,它就可以进行类型检查:

@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]
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读