特质是Scala里代码复用的基础单元。特质封装了方法和字段的定义,并可以通过混入到类中重用它们。与类继承时每个类都只能继承唯一的超类不同,类可以混入任意多个特质。最常用到的两种方式:拓宽瘦接口为胖接口,定义可堆叠的改变。
7.1 如何工作
特质的定义除了使用关键字trait之外,与类定义无异。
特质就像带有具体方法的Java接口。不过它可以做更多,比如声明字段和维持状态值。可以用特质的定义做几乎类的所有事情,除了以下两点。其一,特质不能有任何类参数,即传递给类的主构造器参数。另一个在于,在类中,super都是静态绑定的,而特质中是动态绑定的。
7.2 瘦接口与胖接口
特质的一种主要的应用方式就是可以根据类已有的方法自动为类添加方法。
7.3 可堆叠的改变
通过混入多种特质的顺序,可以定义出多种不同的类。
7.4 不是多继承
特质与多继承的差别最重要的在于super的解释。对于多重继承来说,super调用导致的方法调用可以在调用发生的地方明确决定。而对于特质来说,方法调用是由类和被混入类的特质的线性化所决定的。这种差别让改动的堆叠成为可能。
7.5 是否使用
如果行为不会被重用,就做成具体类。
如果要在多个不相关的类中重用,就做成特质。
如果希望从Java代码中继承它,就做成抽象类。
如果计划以编译后的方式发布,并希望外部组织能写一些继承自它的类,倾向于抽象类。
如果效率非常重要,则应使用类。