抽象类与特质的区别

时间:2010-01-05 11:29:04

标签: scala abstract-class traits

  

可能重复:
  Scala traits vs abstract classes

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

4 个答案:

答案 0 :(得分:70)

一个类只能extend one superclass,因此只能有一个抽象类。如果要组合多个类,Scala的方法是使用mixin class composition:组合(可选)超类,您自己的成员定义和一个或多个traits。与类相比,特性受到限制,因为它不能具有构造函数参数(比较scala reference manual)。

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

答案 1 :(得分:52)

特征的一个方面是它们是可堆叠的。允许有约束形式的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的分辨率反映了继承层次结构的线性化。

答案 2 :(得分:13)

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

我建议在具有独立含义的情况下使用抽象类,并在您只想以面向对象的方式添加功能时使用特征。 如果您不确定两者之间,您可能会发现,如果您的所有方法都围绕着做一件事,那么您可能想要一个特征。

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

答案 3 :(得分:5)

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

Traits类似于Java接口,但允许具有方法实现。