在 Scala 中混合多个特征
快速说明:教程中的示例Scala for Java 难民第 5 部分:特征和类型。
假设我具有学生、工人、低薪和年轻人的特征。
我如何声明一个具有所有这些特征的类(不是实例),CollegeStudent?
注意:我知道最简单的情况,例如具有一两个特征的 CollegeStudent:
class CollegeStudent extends Student with Worker
Quick note: Examples from the tutorial Scala for Java Refugees Part 5: Traits and Types.
Suppose I have the traits Student, Worker, Underpaid, and Young.
How could I declare a class (not instance), CollegeStudent, with all these traits?
Note: I am aware of the simplests cases, such as CollegeStudent with one or two Traits:
class CollegeStudent extends Student with Worker
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这很容易,在声明一个类时,您只需根据需要经常使用“with”关键字即可,
如果某个特征正在改变类的行为,则特征的顺序可能很重要,这一切都取决于您正在使用的特征。
另外,如果您不想拥有一个始终使用相同特征的类,您可以稍后使用它们:
It is easy, when declaring a class you just use the "with" keyword as often as you want
the order of the traits can be important if a trait is changing the behavior of the class, it all depends on traits you are using.
Also if you don't want to have a class which always uses the same traits you can use them later:
我认为不仅解释语法,而且解释特征的排序扮演什么角色也非常重要。 我发现 Jason Swartz 的学习 Scala(第 177 页)中的解释非常有启发性。
Scala 类可以一次扩展多个特征,但 JVM 类只能扩展一个父类。 Scala 编译器通过创建“每个特征的副本来形成一个高的、单列的层次结构”来解决这个问题。
类和特征”,这一过程称为线性化。
在这种情况下,使用相同的字段名称扩展多个特征将无法编译,完全相同的“就像您正在扩展一个类并提供您自己的方法版本,但未能添加覆盖关键字”。
并且由于它决定了继承树的形状,因此线性化顺序确实是一个非常重要的问题举个例子,
类 D 用 B 和 C 扩展 A
(其中 A 是一个类,B 是一个类)。和 C 是特征)将成为
class D extends C extends B extends A
。 以下几行(也来自本书)完美地说明了这一点:对 new D() 的调用将使 REPL 打印以下内容:
这完美地反映了线性化继承图的结构。
I think that it is very important to explain not only the syntax, but also which role does the ordering of the traits play. I found the explanation in Jason Swartz's Learning Scala (page 177) quite enlightning.
A Scala class can extend multiple traits at once, but JVM classes can extend only one parent class. The Scala compiler solves this by creating "copies of each trait to form a tall, single-column hierarchy of the
class and traits", a process known as linearization.
In this context, extending multiple traits with identical field names would fail to compile, exactly the same "as if you were extending a class and providing your own version of a method but failed to add an override keyword".
And since it determines the shape of the inheritance tree, the linearization order is indeed one very important question to regard. As an example,
class D extends A with B with C
(where A is a class and Band C are traits) would become
class D extends C extends B extends A
. The following few lines, also from the book, illustrate that perfectly:A call to
new D()
would have the REPL print the following:Which perfectly reflects the structure of the linearized inheritance graph.