在Racket的class系统中,augment、overment、augride等是做什么的?

In Racket's class system, what do augment, overment, augride, etc. do?

Racket 的文档仅部分描述了 augmentpubment 的作用:augment 制作了一个在 superclass 版本的方法之后执行的方法,而pubment 生成一个方法,如果它是在子 class.

中定义的,则该方法将隐式具有 augment 属性

文档完全没有提到 overmentaugride,我无法根据他们的名字猜测他们会做什么。它们是什么,它们之间有什么区别?

Racket 的 class 系统相对较大的继承函数家族,正如您所描述的,有点令人困惑,而且它们有些可爱的名字并不总是有帮助。

为了理解这一点,Racket 提供了两种独立的方法继承机制。

  • public 方法对应于其他 OO 模型中 public 方法的 class 逻辑思想。用 public 声明的方法可以在子 class 中被覆盖,除非它们被声明为 final,在这种情况下它们不能。
  • pubment方法类似,但不能覆盖,只能增强.扩充一个方法类似于覆盖它,但是调度调用 superclass 的实现而不是 subclass 的实现。

为了阐明覆盖和扩充之间的区别,当调用覆盖方法时,将执行覆盖实现,这可能可选调用超级class的通过 inherit/super 实施。相比之下,在增强方法中,superclass 的实现接收控制,它可以选择通过 inner.

调用 subclass 的实现

现在,我们还提供了public-finaloverride-final augment-final。这些很简单。用 public-final 声明一个方法意味着它既不能被扩充也不能被覆盖。使用 override-final 覆盖 superclass 的 public 方法,但它不允许任何 further 覆盖。最后,augment-final 是相似的,但是对于用 pubment 声明的方法,而不是 public.

那么,overmentaugride 这两个奇怪的混合体呢?

  • overment 可用于实现 初始定义 public 的方法。这 "converts" 它们是可扩充的方法,而不是所有 class 的子 class 的可覆盖方法。
  • augride方向相反。它将可扩充方法转换为可覆盖方法,但覆盖实现仅替换扩充,而不是原始实现。

总结一下:

  • public, pubment, public-final superclass.
  • 中不存在的所有 declare 方法
  • 然后我们有一系列用于扩展 superclass 方法的形式:
    • overrideaugment 扩展用 public 声明的方法pubment,分别使用相关行为。
    • override-finalaugment-final 与它们的非最终版本相同,但防止进一步覆盖或增强。
    • overmentaugride 将可覆盖方法转换为可扩充方法,反之亦然。

对于另一个更全面的解释,您可能有兴趣看一下 the paper from which Racket's model was derived,它非常易读并且包含一些有用的图表。