什么是可堆叠修改?

9

我正在阅读一本关于Scala的书,其中提到使用特质(traits)进行 可堆叠修改。什么是 可堆叠修改,它们有什么用途?


这本书在特质章节中进行了解释。 - Rayne
2个回答

10

在Scala中,区分可堆叠修改(即该术语在Scala中的使用方式)的基本特性是,“super”受到混入trait的动态影响,而一般情况下,“super”是一个静态确定的目标。

如果您写:

abstract class Bar { def bar(x: Int): Int }
class Foo extends Bar { def bar(x: Int) = x }

那么对于Foo,“super”将始终是Bar。

如果您编写

trait Foo1 extends Foo { abstract override def bar(x: Int) = x + super.bar(x) }

然后对于那个方法,只有在类被创建之后,super才会变得可知。
trait Foo2 extends Foo { abstract override def bar(x: Int) = x * super.bar(x) }

scala> (new Foo with Foo2 with Foo1).bar(5)
res0: Int = 30

scala> (new Foo with Foo1 with Foo2).bar(5)
res1: Int = 50

为什么这很有趣?举个例子,假设你有一些数据需要进行压缩、加密和数字签名。你可能想先压缩再加密再签名,或者先加密再签名再压缩等等。如果你按照这种方式设计你的组件,你可以实例化一个定制化的对象,其中包含你想要的位按你想要的方式组织。


为了优雅起见,“trait Foo1 extends Bar”而不是“trait Foo1 extends Foo”? - Boris Pavlović
Boris - 你说得完全正确,这只是因为我最后一分钟添加了 Bar 才写成这样。 - psp

1

我看了Real-World Scala presentation,其中提到了“可堆叠修改”这个术语。显然,它是指在覆盖时调用超级方法的特质,从而添加功能而不是替换它。因此,您可以使用特质累积功能,在Java中我们经常使用方面。Trait扮演着方面的角色,覆盖“有趣”的方法并添加特定的功能,例如日志记录等,然后调用super并将“球”传递给链中的下一个trait。希望对你有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接