Scala 抽象类与特质的区别

Scala 抽象类与特质的区别,scala,abstract-class,traits,Scala,Abstract Class,Traits,可能重复: 抽象类和traits在概念上有什么区别?至少在Scala中,traits系统有一种明确的方式来声明子类中的父优先级,以避免与多重继承相关的典型问题,即与具有相同签名的继承方法冲突 trait类似于Java接口,但允许有方法实现 从概念上讲,特征是类的一个组成部分,而不是类本身。因此,它通常没有构造函数,也不意味着“独立” 我建议当抽象类具有独立的含义时使用它,当您只想以面向对象的方式添加功能时使用它如果你不确定两者之间的区别,你可能会发现,如果你所有的方法都围绕着做一件事,你可能想

可能重复:


抽象类和traits在概念上有什么区别?

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


trait类似于Java接口,但允许有方法实现

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

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


例如(非特定语言),如果您的员工同时扩展“Person”和“Cloneable”,则将Person作为基类,Cloneable作为特征。

特征的一个方面是它们是可堆叠的。允许AOP的约束形式(围绕建议)

super
的解析反映了继承层次结构的线性化。

一个类只能,因此只能有一个抽象类。如果您想组合几个类,Scala的方法是:组合一个(可选)超类、您自己的成员定义和一个或多个。与类相比,trait受到限制,因为它不能有构造函数参数(比较)


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

你看到了吗?在这个问题上有一些回应的元素。我想说,当所有的方法都围绕着做一件事,你的设计是好的(单一责任原则:)。否则,设计应该是一个可辩护的折衷方案。你说得对,我稍微澄清了我的答案。只要层次结构是一棵树,就不会遇到复杂的场景。@编辑:如果超类型不继承相同的特性,就可以有冲突。任何两个具有相同名称和参数(类型)列表的方法都有冲突。@Raphael说得对。我试图澄清这一点。现在是对的吗?我想是的。可能值得注意的是,Scala以一种定义良好的方式解决了此类冲突(“稍后”特性具有优先权)。现在,我不明白为什么同样的技术不能解决类多重继承问题,所以我不知道特征的限制是否真的是因为它。@andershqst你可以滥用某些东西只是一个根本不使用某些东西的微弱理由。如果你想从java代码中调用一些东西,最好让它(例如trait)实现一个java接口。与接口相比,trait的一个优点是,您可以在不破坏其他代码的情况下对其进行扩展。(不过,你必须重新编译它。)我也看到了traits的很好的用途,你可以通过只包含一个trait来使用基本算法的变体。例如,在标准库中,“new TreeSet”提供了一个基本集,“new TreeSet with SynchronizedSet”是同步的。绑定优先级不是通过特征本身来解决的,而是通过超级类型列表的线性化来解决的。你可以用多类继承来做同样的事情。酷。。。如果两个特征X和Y为def a产生不同的值会怎样?对不起@托马斯:有一些规则,你做了错误的解释,不幸的是我投了你一票。
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