假设我们有两个特点:
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 {}
编译得很好。你能提供一个正确的解释吗?
答案 0 :(得分:8)
从技术上讲,您无法直接实例化单个特征或多个混合特征,但编译器使用一些语法糖,允许您创建扩展它们的匿名类。假设我们有:
curl http://localhost:8080/metrics | jq
当你致电trait A
trait B
时,真正发生的事情是编译器正在创建一个混合了new A with B
和A
的匿名类。你得到:
B
当你致电final class $anon extends A with B
new $anon()
时,同样的事情发生了。你得到一个扩展new A {}
的匿名类:
A
唯一的区别是语法。从单个特征创建匿名类时,您至少需要使用大括号final class $anon extends A
new $anon()
来区分它。也就是说,更容易辨别模板是否可以构造,或者必须包装在要构造的匿名类中。使用多个特征(甚至是混合了特征的类),编译器会理解总是需要首先创建一个匿名类。
总结:
{}