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



假设我们有两个特征:

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 {}编译的很好。您能提供适当的解释吗?

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

trait A
trait B

当您调用new A with B时,真正发生的是编译器正在创建一个匿名类,该类同时混合了AB。你得到:

final class $anon extends A with B
new $anon()

当您致电new A {}时,也会发生同样的事情。您将获得一个扩展A的匿名类:

final class $anon extends A
new $anon()

唯一的区别是句法。从单个特征创建匿名类时,您至少需要使用括号{}将其与类区分开。也就是说,更容易辨别模板是否可以构造,或者必须包裹在匿名类中才能构造。具有多个特征(甚至具有混合特征的类别),编译器知道它将始终首先创建一个匿名类。

总结:

class C
new A {}       // Anonymous class that extends A, then constructed
new A with B   // Anonymous class that extends A with B, then constructed
new C          // Constructed instance of class C
new C with A   // Anonymous class that extends C with A, then constructed

相关内容

最新更新