|
|
1
347
我能想到两个不同点
|
|
|
2
186
在scala中有一个部分叫做 "To trait, or not to trait?" 它解决了这个问题。因为第一版的ED是在线的,我希望它可以引用这里的全部内容。(任何严肃的scala程序员都应该买这本书):
正如@mushtaq ahmed所提到的,特性不能有任何参数传递给类的主构造函数。
另一个区别是
其余部分见 Chapter 12 了解更多详细信息。 编辑1(2013): 抽象类的行为方式与特征有细微的区别。线性化规则之一是它保留了类的继承层次结构,这种继承层次结构倾向于将抽象类推送到链的后面,而特性可以很好地混合在一起。在某些情况下,处于类线性化的后一个位置实际上更可取,因此抽象类可以用于此目的。见 constraining class linearization (mixin order) in Scala . 编辑2(2018): 从scala 2.12开始,trait的二进制兼容性行为发生了变化。在2.12之前,添加或删除特性的成员需要重新编译继承特性的所有类,即使这些类没有更改。这是因为特性在JVM中的编码方式。 从scala 2.12开始,特征 compile to Java interfaces 所以这个要求已经放宽了一点。如果特性有以下任何一种,它的子类仍然需要重新编译:
但是如果特性不存在,那么您现在可以在不破坏二进制兼容性的情况下更新它。 |
|
|
3
75
不管它值多少钱,奥德斯基等人 Programming in Scala 建议,当你怀疑的时候,你使用特质。如果需要的话,可以在以后将它们更改为抽象类。 |
|
|
4
19
除了不能直接扩展多个抽象类,但是可以将多个特性混合到一个类中之外,值得一提的是,特性是可堆叠的,因为特性中的超级调用是动态绑定的(它指的是在当前特性之前混合的一个类或特性)。 从托马斯的回答 Difference between Abstract Class and Trait :
|
|
|
5
9
当扩展抽象类时,这表明子类是类似的。我认为,在使用特性时,这种情况是不必要的。 |
|
|
6
7
在 Programming Scala 作者认为抽象类形成了一种经典的面向对象的“IS-A”关系,而特征是一种scala组合方式。 |
|
|
7
5
抽象类可以包含行为-它们可以用构造函数参数化(而特性不能),并表示一个工作实体。特性只代表一个特性,一个功能的接口。 |
|
|
8
1
|
|
|
RedCrafter LP · 用隐式生命周期方法实现外来特质 1 年前 |
|
|
Taz · 覆盖第三方库中的Drop特性 2 年前 |
|
|
rockerbacon · Rust惯用的方法是什么? 2 年前 |
|
Makogan · 如何调用存储在Box中的dyn函数? 2 年前 |
|
|
apt1002 · 为什么Deref式的特质不构成? 2 年前 |
|
|
mozboz · 是否将trait指定为枚举变量值? 2 年前 |
|
|
tcerqueira · 如何引用不使用生存期参数的结构的生存期 2 年前 |