Trait mixin like interface,即'with'关键字,不扩展类

时间:2016-06-20 13:33:14

标签: scala traits

trait A
> defined trait A

class B extends A
> defined class B

class C with A
> <console>:1: error: ';' expected but 'with' found.
  class C with A
          ^

然而,如果我从AnyRef(不应该需要)添加C类扩展,那么最后一个语句可以正常工作。

class C extends AnyRef with A
> defined class C

语言语法中是否缺少这些内容?或任何特定的概念原因?从概念上讲,我认为class B extends Aclass B with A是不同的。

PS:尝试寻找类似的问题或错误“';'预期,但'找到'。“。如果已经回答,请标记重复。

3 个答案:

答案 0 :(得分:0)

关于C extends B读取以及C extends B with A这一事实,而C with B从句子的角度看起来有点奇怪,我总是理解with属于B超级类型,而不是基类C

因此,对于匿名类,我读new B with A为&#34;一个匿名类,用A&#34;扩展B。

结果,class C extends B with A我理解为&#34;一个名为C的新类,用A&#34扩展B;

所以class C extends B是&#34;一个名为C的新类,它扩展了(类或特征)B,没有别的&#34;。

在这个视角中,class C with B将是一个无意义的表达,因为&#34;这句话没有动词&#34;。

答案 1 :(得分:0)

最常见的类定义形式是

class c[tps] as m(ps1)…(psn) extends t (n≥0).

...

t

形式的模板

sc with mt1 with … with mtm { stats } // m≥0

定义类的对象的基类,行为和初始状态。可以省略extends子句extends sc with mt1 with … with mtm,在这种情况下可以使用extends scala.AnyRef

http://www.scala-lang.org/files/archive/spec/2.11/05-classes-and-objects.html#class-definitions

答案 2 :(得分:0)

scala-lang论坛中找到了类似的问题,并由Martin Odersky回答

  

我们在Scala的设计早期就有了这个惯例。人们发现了   令人困惑。这就是为什么我们改为永远使用extends我的方式   看到它是这样的:

     

A类用C {...}

扩展B.      

应该分解为:

     

A类扩展&lt;&lt;&lt; B与C {...}&gt;&gt;&gt;

     

也就是说,A是一个用C {扩展匿名模板B的类   ......}。无论该模板是以类还是类开头都没关系   特质。

     

新约定的另一个优点是子类不是   当一个类被改变为一个特征时,或者反之亦然   这种情况经常发生且很自然。

     

干杯

     

- 马丁