可能重复:
Scala 特征与抽象类
抽象类和特征之间的概念区别是什么?
一个类只能扩展一个超类,因此只能扩展一个抽象类。如果你想组合几个类,Scala 的方法是使用mixin 类组合:你组合一个(可选的)超类、你自己的成员定义和一个或多个特征。与类相比,特征受到限制,因为它不能具有构造函数参数(比较scala 参考手册)。
The restrictions of traits in comparison to classes are introduced to avoid typical problems with multiple inheritance. There are more or less complicated rules with respect to the inheritance hierarchy; it might be best to avoid a hierarchy where this actually matters. ;-) As far as I understand, it can only matter if you inherit two methods with the same signature / two variables with the same name from two different traits.
特征的一个方面是它们是可堆叠的。允许 AOP 的约束形式(围绕建议)。
trait A{
def a = 1
}
trait X extends A{
override def a = {
println("X")
super.a
}
}
trait Y extends A{
override def a = {
println("Y")
super.a
}
}
scala> val xy = new AnyRef with X with Y
xy: java.lang.Object with X with Y = $anon$1@6e9b6a
scala> xy.a
Y
X
res0: Int = 1
scala> val yx = new AnyRef with Y with X
yx: java.lang.Object with Y with X = $anon$1@188c838
scala> yx.a
X
Y
res1: Int = 1
的分辨率super
反映了继承层次的线性化。
从概念上讲,特征是类的组成部分,而不是类本身。因此,它通常没有构造函数,也不意味着“独立存在”。
我建议在具有独立含义时使用抽象类,而在您只想以面向对象的方式添加功能时使用特征。如果您不确定两者之间的关系,您可能会发现,如果您的所有方法都围绕做一件事情,您可能需要一个 trait。
对于(非特定于语言的)示例,如果您的 Employee 应该同时扩展“Person”和“Cloneable”,则将 Person 设为基类,将 Cloneable 设为 trait。
至少在 Scala 中,traits 系统有一种明确的方式在子类中声明父优先级,以避免与多重继承相关的典型问题,即与具有相同签名的继承方法冲突。
Traits 类似于 Java 接口,但允许具有方法实现。