【问题标题】:Groovy's extension-module compared to java's inheritanceGroovy 的扩展模块与 java 的继承相比
【发布时间】:2015-07-04 22:13:01
【问题描述】:

groovy 的扩展模块特性是 java 继承特性的混合形式吗?为什么扩展模块需要声明为静态?

【问题讨论】:

  • 从继承的角度考虑扩展模块是个坏主意。他们用额外的行为扩展了一个特定的类:所以他们正在修改现有的继承层次结构,而不是为它做出贡献……但他们的上下文确实集中在一个类上(所以再次忽略继承)。其他语言具有类似的构造作为第一类类型定义的一部分(Go、Scala、Kotlin...)。它们是静态的,因为它们是在其运行时绑定环境之外定义的:,因此接收实例作为参数(再次类似于其他语言的方法)。

标签: java groovy gdk extension-modules


【解决方案1】:

简短的回答是我认为是的。很难清楚地回答,因为扩展方法的继承完全由运行时(和静态编译器)完成。因此它与 Java 如何进行继承无关。

回答第二个问题...它们是静态的,因为对于需要状态的情况,您通常使用元类。扩展方法最初被认为是方便方法或使 API 更 Groovy。因此,它们是添加到元类中的一种特殊形式的方法。您可以将它们视为简化版本。但这也意味着他们没有所有的能力。实现扩展方法,可以在每个“自我”对象的基础上保持本地状态(基本上是字段/属性会做什么)实际上很难做到高效......但你总是可以为此使用每个实例的元类。

【讨论】:

    【解决方案2】:

    出于所有广泛的目的,它们都是语法糖,因此静态方法看起来更像 OOP。没有继承,因为 Java 和 Groovy 中的静态方法不参与继承(即类不继承静态方法)。

    方法需要是静态的,因为编译器不知道如何实例化扩展方法的周围类。

    但是我相信有些语言确实允许在封闭类之外定义方法并进行某种继承,但不是很多(我相信 CLOS 和 Dylan 会这样做)。此外,它们还有许多似乎允许添加方法的语言,但“对象”的类型实际上已更改/隐藏为其他类型。这称为 adhoc 多态性(例如 Clojure、Haskell、Golang 和 Scala),但又与包含多态性(Java 继承)无关。

    【讨论】:

      【解决方案3】:

      很遗憾,reference documentation 和其他文档没有定义扩展方法的语义:

      • 问。他们可以覆盖实例方法吗?
        我通过use Category 方法和metaClass expando 方法测试了扩展方法。两种方法都不会覆盖实例方法。我没有测试通过module descriptor 安装的extension modules
      • 问。它们可以被子类的扩展方法覆盖吗?
        我也测试过。 use 方法和 metaClass 扩展方法不会被子类的扩展方法覆盖。
      • 问。他们可以调用继承的super 方法吗?
        不,因为它们是通过 static 方法实现的。
      • 问。他们可以调用私有方法吗?
        实验表明,令人惊讶的是,它们可以做到。
      • 问。他们可以访问私有实例变量吗?
        不,因为它们是通过 static 方法实现的。
      • 问。它们可以从 Java 方法调用吗?
        也许,if the extension module is on the classpath 在编译调用代码时。我没有测试它。

      结论: 扩展方法不是继承的一种形式。它们似乎是Universal Function Call Syntax (UFCS)的动态形式,也就是语言找不到的时候一个方法variable.foo(arguments) 它寻找一个静态扩展函数foo(variable, arguments) 来调用。 [如果错误,请纠正我的假设!]

      您问为什么它们被定义为static。这似乎符合语义:一个不涉及继承的静态函数,尽管它的调用语法使它看起来像一个方便的方法调用。

      您可以使用@groovy.lang.Category 注解编写类似实例方法的扩展方法。这会在编译时进行 AST 转换以将其转换为合适的静态方法。

      另见Groovy traits。这一种(混合)继承形式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-21
        • 2010-11-11
        • 2012-01-30
        • 1970-01-01
        • 2020-04-11
        • 2013-09-26
        • 2015-02-27
        • 2016-05-27
        相关资源
        最近更新 更多