scala 抽象类和特征之间的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2005681/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between Abstract Class and Trait
提问by Red Hyena
Possible Duplicate:
Scala traits vs abstract classes
可能的重复:
Scala 特征与抽象类
What is the conceptual difference between abstract classes and traits?
抽象类和特征之间的概念区别是什么?
采纳答案by Hans-Peter St?rr
A class can only extend one superclass, and thus, only one abstract class. If you want to compose several classes the Scala way is to use mixin class composition: you combine an (optional) superclass, your own member definitions and one or more traits. A trait is restricted in comparison to classes in that it cannot have constructor parameters (compare the scala reference manual).
一个类只能扩展一个超类,因此只能扩展一个抽象类。如果您想组合多个类,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.
引入了与类相比特征的限制,以避免多重继承的典型问题。关于继承层次,有或多或少复杂的规则;最好避免在这实际上很重要的层次结构。;-) 据我所知,只有从两个不同的特征继承两个具有相同签名的方法/两个具有相同名称的变量才重要。
回答by Thomas Jung
One aspect of traits is that they are a stackable. Allowing a constrainted form of AOP (around advice).
特征的一个方面是它们是可堆叠的。允许约束形式的 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@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@188c838
scala> yx.a
X
Y
res1: Int = 1
The resolution of superreflects the linearization of the inheritance hierarchy.
的分辨率super反映了继承层次的线性化。
回答by Oak
Conceptually, a trait is a component of a class, not a class by itself. As such, it typically does not have constructors, and it is not meant to "stand by itself".
从概念上讲,特征是类的组成部分,而不是类本身。因此,它通常没有构造函数,并且它并不意味着“独立”。
I suggest using an abstract class when it has an independent meaning, and traits when you just want to add functionality in an object-oriented manner. If you're not sure between the two, you might find that if all your methods revolve around doing a single thing, you probably want a trait.
我建议在具有独立含义时使用抽象类,当您只想以面向对象的方式添加功能时使用特征。如果您不确定两者之间的关系,您可能会发现如果您的所有方法都围绕做一件事情,那么您可能需要一个特征。
For a (non-language-specific) example, if your Employee should extend both "Person" and "Cloneable", make Person a base class and Cloneable a trait.
对于(非特定于语言的)示例,如果您的 Employee 应扩展“Person”和“Cloneable”,则将 Person 设为基类,将 Cloneable 设为特征。
回答by Illotus
At least in Scala, the traits system has an explicit way of declaring parent priority in a subclass to avoid typical problems associated with multiple inheritance, i.e. conflicts with inherited methods having the same signature.
至少在 Scala 中,traits 系统有一种在子类中声明父优先级的显式方法,以避免与多重继承相关的典型问题,即与具有相同签名的继承方法冲突。
Traits are akin to Java interfaces, but are allowed to have method implementations.
Traits 类似于 Java 接口,但允许有方法实现。

