为什么可以在Scala中实例化多个特征,而不是单个特征?

时间:2017-02-23 15:58:05

标签: scala inheritance instantiation multiple-inheritance traits

假设我们有两个特点:

trait Trait1
trait Trait2

如果我尝试val single = new Trait1之类的内容,我会收到错误error: trait Trait1 is abstract; cannot be instantiated。但是,val twoTraits = new Trait1 with Trait2编译。为什么会这样?

P.S。我还观察到val single = new Trait1 {}编译得很好。你能提供一个正确的解释吗?

1 个答案:

答案 0 :(得分:8)

从技术上讲,您无法直接实例化单个特征或多个混合特征,但编译器使用一些语法糖,允许您创建扩展它们的匿名类。假设我们有:

curl http://localhost:8080/metrics | jq 

当你致电trait A trait B 时,真正发生的事情是编译器正在创建一个混合了new A with BA的匿名类。你得到:

B

当你致电final class $anon extends A with B new $anon() 时,同样的事情发生了。你得到一个扩展new A {}的匿名类:

A

唯一的区别是语法。从单个特征创建匿名类时,您至少需要使用大括号final class $anon extends A new $anon() 来区分它。也就是说,更容易辨别模板是否可以构造,或者必须包装在要构造的匿名类中。使用多个特征(甚至是混合了特征的类),编译器会理解总是需要首先创建一个匿名类。

总结:

{}