快速提示:示例来自教程Scala for Java Refugees Part 5: Traits and Types。在Scala中混合多重特性
假设我有特质学生,工人,欠薪和年轻人。
我该如何申报一个班级(而不是实例),CollegeStudent,具备所有这些特质?
注:我知道的simplests情况下,如CollegeStudent有一个或两个特点:
class CollegeStudent extends Student with Worker
快速提示:示例来自教程Scala for Java Refugees Part 5: Traits and Types。在Scala中混合多重特性
假设我有特质学生,工人,欠薪和年轻人。
我该如何申报一个班级(而不是实例),CollegeStudent,具备所有这些特质?
注:我知道的simplests情况下,如CollegeStudent有一个或两个特点:
class CollegeStudent extends Student with Worker
这是很容易,声明一个类时,你只是“同向”经常关键字使用只要你想
class CollegeStudent extends Student with Worker with Underpaid with Young
如果性状改变类的行为特征的顺序也很重要,这一切都取决于你所使用的特征。
此外,如果你不希望有它总是使用相同性状的类,你可以在以后使用它们:
class CollegeStudent extends Student
new CollegeStudent with Worker with Underpaid with NotSoYoungAnymore
我认为,这说明不仅语法是非常重要的,但这些性状的排序也扮演着什么角色。我在Jason Swartz的Learning Scala(第177页)中找到了相当启发的解释。
Scala类可以一次扩展多个特征,但JVM类只能扩展一个父类。 Scala编译器通过创建每个特征的“副本以形成 类和特征”的高单列层次结构来解决该问题,该过程被称为线性化。
在此背景下,扩大与相同的字段名多性状会出错,一模一样的“,如果你是扩展一个类,并提供自己的方法的版本,但没有添加替代关键字” 。
由于它决定了继承树的形状,所以线性化顺序的确是一个非常重要的问题。举例来说,class D extends A with B with C
(其中A是一个类别,B 和C是特征)将变为class D extends C extends B extends A
。下面的几行字,也从书中,说明了完美:
trait Base { override def toString = "Base" }
class A extends Base { override def toString = "A->" + super.toString }
trait B extends Base { override def toString = "B->" + super.toString }
trait C extends Base { override def toString = "C->" + super.toString }
class D extends A with B with C { override def toString = "D->" + super.toString }
到new D()
的调用将有REPL打印以下:
D->C->B->A->Base
这很好地反映了线性继承图的结构。
???问一个问题,然后自我调整 – 2009-07-05 18:36:56
很久以前,我曾在Eclipse上尝试过一次,但这并没有奏效。升级之后,写下测试我想:“也许我会尝试一下,看看我能否自己找到它”。 – 2009-07-05 20:59:53