我是 Scala 的新手,开始学习这门语言是为了好玩,但我仍在努力解决它。我对 Scala 特征的理解是,它们类似于 java 接口,只是某些方法可以有实现。
Java 8 正在添加可以具有可以提供实现的默认方法的接口。
Java 8 接口和 Scala 特征之间有什么异同?
Java 8 的默认方法和 Scala 特征的动机不同。
引入前者是为了支持安全的 API 演进和有限形式的多重继承。利用 Project Lambda 中的函数式编程习惯用法,在不改变所有可能的实现者的情况下向 java.util.Collection
接口添加例如 forEach(lambda)
方法是有益的(如果不破坏向后兼容性,这实际上是不可能做到的) )。作为副作用,它还提供了一种 mixin composition 形式。
Scala 特征 是从头开始设计的,作为模块化组件组合的构建块。它们对多重继承友好,并且由于线性化而对混入的评估顺序有严格的规则,因此没有 diamond problem。它们还支持状态,可以引用实现类并对可以混入它们的类型进行限制。查看彻底使用特征的 Scala 集合库。
请注意,使用 scala 2.12.0 RC1 (Sept. 2016),Trait
现在可以编译为接口。
Scala 2.12 旨在充分利用 Java 8 的新功能
Java 8 允许在接口中使用具体方法,Scala 2.12 能够将 trait 编译为单个接口。以前,特征被表示为包含方法实现和接口的类。请注意,编译器仍然需要在幕后执行相当多的魔法,因此如果要在 Java 中实现 trait,则必须小心。 (简而言之,如果一个 trait 执行以下任何操作,它的子类需要合成代码:定义字段、调用 super、body 中的初始化语句、扩展一个类、依靠线性化在正确的 super trait 中找到实现。)
参见scala PR 5003更多的实现差异。
在相似性上,两者都可以有默认方法,
差异方面,我们可以将特征添加到唯一的实例,而不是整个类。例子:
trait A { def m = ??? }
class B
new B() with A
同样,我们可以继续在实例上添加特征层。