87

我是 Scala 的新手,开始学习这门语言是为了好玩,但我仍在努力解决它。我对 Scala 特征的理解是,它们类似于 java 接口,只是某些方法可以有实现。

Java 8 正在添加可以具有可以提供实现的默认方法的接口。

Java 8 接口和 Scala 特征之间有什么异同?

4

3 回答 3

48

Java 8 的默认方法Scala 特征的动机不同。

引入前者是为了支持安全的 API 演进和有限形式的多重继承。通过利用 Project Lambda 中的函数式编程习惯用法,添加例如接口forEach(lambda)方法java.util.Collection而不改变所有可能的实现者是有益的(如果不破坏向后兼容性,这实际上是不可能做到的)。作为副作用,这也提供了一种mixin 组合

Scala 特征是从头开始设计的,作为模块化组件组合的构建块。它们是多重继承友好的,并且由于线性化而对混合的评估顺序有严格的规则,因此不存在菱形问题。它们还支持状态,可以引用实现类并对可以混入它们的类型进行限制。查看彻底使用特征的 Scala 集合库。

于 2013-05-28T12:00:54.057 回答
14

请注意,使用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更多的实现差异。

于 2016-09-18T19:56:01.873 回答
6

在相似性上,两者都可以有默认方法,

差异方面,我们可以将特征添加到唯一的实例,而不是整个类。例子:

trait A { def m = ??? }
class B 

new B() with A 

同样,我们可以继续在实例上添加特征层。

于 2018-12-05T05:53:33.087 回答