Scala特质与Java 8接口之间的区别和相似之处是什么?

88
我刚接触Scala,学习这门语言很有趣,但仍在努力理解它。我对Scala特质的理解是,它们类似于Java接口,不同之处在于某些方法可以有实现。
Java 8引入了可以具有默认方法和实现的接口。
Java 8接口和Scala特质之间的相似点和差异是什么?

4
请访问这个网站,它可能对你有帮助:http://www.infoq.com/articles/java-8-vs-scala - akki0996
3
虚拟扩展方法(默认方法)的主要推动力是API演变。一个欢迎的副作用是它们提供了一种行为上的多继承形式。Scala中的特质不仅提供了行为的多继承,还提供了状态的多继承。除了状态和行为继承外,特质还提供了获取实现类引用的手段...相比之下,Scala中的特质提供了比Java 8的虚拟扩展方法更丰富的功能集。 - Brice Roncace
你想过将其中一个特质封装在另一个特质下面吗? - Alonso del Arte
3个回答

49

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

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

Scala traits是从头设计的模块化组件构建块。它们友好支持多继承,并通过线性化的严格规则对混合的评估顺序避免了钻石问题。它们还支持状态,可以引用实现类并对可以混合它们的类型进行限制。请查看Scala集合库,其中广泛使用了traits。


2
你能详细阐述一下“Scala特质是从头开始设计的,作为模块化组件构建的基本单元”吗? - Adelin

15
请注意,从scala 2.12.0 RC1 (Sept. 2016)开始,Trait现在编译为一个接口。
Scala 2.12的重点是充分利用Java 8的新特性。
随着Java 8允许在接口中使用具体方法,Scala 2.12能够将trait编译为单个接口。在此之前,Trait被表示为一个包含方法实现和接口的类。
需要注意的是,编译器仍然需要执行相当多的魔法操作,因此如果要在Java中实现Trait,则必须小心处理。
简而言之,如果Trait执行以下任何操作,则其子类需要合成代码:定义字段、调用super、在主体中使用初始化语句、扩展类、依赖线性化以找到正确超级Trait中的实现。
请查看scala PR 5003以了解实现的差异。

7

关于相似性,两者都可以具有默认方法,

而在差异方面,我们只能为实例添加特征,而不能为整个类添加。例如:

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

new B() with A 

同样的,我们可以在一个实例上不断添加 trait 层。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接