Scala中抽象特征的语义

时间:2012-02-19 12:04:41

标签: scala abstract traits

我想知道将abstract关键字与trait结合使用的语义是什么。

如果特征没有定义任何抽象方法,abstract关键字不会阻止我创建实例:

scala> abstract trait T
defined trait T

scala> new T{}
res0: java.lang.Object with T = $anon$1@12cd927d

另一方面,如果特征确实定义了抽象方法,那么无论abstract关键字是否存在,我都无法创建实例(当然不实现此方法):

scala> abstract trait T { def foo : Unit }
defined trait T

scala> new T{}
<console>:9: error: object creation impossible, since method foo in trait T of type =>    Unit is not defined
              new T{}
                  ^

scala> trait T { def foo : Unit }
defined trait T

scala> new T{}
<console>:9: error: object creation impossible, since method foo in trait T of type =>     Unit is not defined
              new T{}
                  ^

那么abstract有用的前面的trait关键字是什么?

2 个答案:

答案 0 :(得分:30)

它没有效果,特征是自动抽象的。

  

abstract修饰符用于类定义。这是多余的   对于特征,对于所有其他不完整的类是强制性的   成员。

http://www.scala-lang.org/docu/files/ScalaReference.pdf

答案 1 :(得分:1)

您没有创建特征的实例。特征无法实例化。

您正在创建一个扩展特征的匿名类的实例。

一般来说,

new __t__

相当于

{ class __anonymous__ extends __t__; new __anonymous__ }

(其中__anonymous__是用户程序无法访问的匿名类的新名称

详见section 6.10 Instance Creation Expressions of the Scala Language Specification

因此,你可以在第一种情况下创建实例的原因是因为你没有创建特征的实例(它是抽象的)而是一个对象(它不是)。

在第二种情况下,您无法创建实例的原因是,如果您继承某些东西,无论是特征还是类,您最终必须按顺序在继承链的某处实现其抽象方法实例化它。在第一种情况下,没有抽象方法可以实现。

abstract关键字本身没有区别:traits是隐式抽象的,关键字是多余的。