抽象类与特质的区别

Red*_*ena 91 abstract-class scala traits

可能重复:
Scala特征与抽象类

抽象类和特征之间的概念差异是什么?

Han*_*örr 70

一个类只能扩展一个超类,因此只能扩展一个抽象类.如果你想组成几个类,Scala方法是使用mixin类组合:你组合一个(可选的)超类,你自己的成员定义和一个或多个特征.与类相比,特性受到限制,因为它不具有构造函数参数(比较scala参考手册).

引入了与类相比的特征限制,以避免多重继承的典型问题.关于继承层次结构,或多或少有复杂的规则; 最好避免这个实际上很重要的层次结构.;-)据我所知,只有从两个不同的特征继承具有相同签名的两个方法/具有相同名称的两个变量才有意义.


Tho*_*ung 53

特征的一个方面是它们是可堆叠的.允许约束形​​式的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
Run Code Online (Sandbox Code Playgroud)

分辨率super反映了继承层次的线性化.

  • 很酷......如果两个特征**X**和**Y**产生不同的def**a**值怎么办? (4认同)

Oak*_*Oak 14

从概念上讲,特质是一个阶级的一个组成部分,而不是一个阶级本身.因此,它通常没有构造函数,并不意味着"独立".

我建议在它具有独立意义时使用抽象类,当你只想以面向对象的方式添加功能时使用traits.如果你不确定两者之间,你可能会发现如果所有的方法都围绕着做一件事,你可能想要一个特征.

对于(非语言特定的)示例,如果您的Employee应该扩展"Person"和"Cloneable",请将Person设为基类,并将Cloneable设为特征.


小智 5

至少在Scala中,traits系统有一种明确的方式来声明子类中的父优先级,以避免与多重继承相关的典型问题,即与具有相同签名的继承方法的冲突.

特征类似于Java接口,但允许具有方法实现.