【问题标题】:Semantics of abstract traits in ScalaScala中抽象特征的语义
【发布时间】:2016-04-01 03:40:13
【问题描述】:

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

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

scala> abstract trait T
defined trait T

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

另一方面,如果 trait 确实定义了一个抽象方法,那么无论 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{}
                  ^

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

【问题讨论】:

  • 你不能创建一个特征的实例。当你说new T{} 时,你创建了一个混合了特征 T 的匿名对象。

标签: scala abstract traits


【解决方案1】:

它没有任何作用,特征是自动抽象的。

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

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

【讨论】:

    【解决方案2】:

    您没有创建特征的实例。特征不能被实例化。

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

    一般来说,

    new __t__
    

    等价于

    { class __anonymous__ extends __t__; new __anonymous__ }
    

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

    这在section 6.10 Instance Creation Expressions of the Scala Language Specification中有详细说明。

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

    在第二种情况下,你不能创建实例的原因是,如果你从某个东西继承,无论是特征还是类,你最终都必须在继承链的某个地方实现它的抽象方法,以便按顺序实例化它。在第一种情况下,没有要实现的抽象方法。

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

    【讨论】:

    • 我认为你的意思是他正在创建一个匿名的class,它具有mixin 的特性。
    • 对不起,是的。作为特征子类的匿名类的实例的对象。唷。
    猜你喜欢
    • 1970-01-01
    • 2011-11-19
    • 2011-01-03
    • 2011-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多