像接口这样的特征混合,即 'with' 关键字并且没有扩展 class

Trait mixin like interface i.e. 'with' keyword and without extending a class

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
          ^

而如果我添加 class C extends from AnyRef(不需要),则最后一条语句可以正常工作。

class C extends AnyRef with A
> defined class C

这是语言语法中缺少的东西吗?或任何特定的概念原因?我认为 class B extends Aclass B with A 在概念上是不同的。

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

关于C extends B读起来和C extends B with A一样好,而C with B从句子的角度看有点奇怪,我一直理解with属于B 超类型,而不是基础 class C.

因此,对于匿名 classes,我读 new B with A 是 "an anonymous class that extends B with A" 的缩写。

因此,class C extends B with A我理解为"a new class named C that extends B with A"

所以 class C extends B 是 "a new class named C that extends (class or trait) B with nothing else"。

从这个角度来看,class C with B 将是一个与 "this sentence no verb".

一样毫无意义的表达式

class定义的最一般形式是

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

...

t 是表单的模板

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

定义了 class 对象的基础 classes、行为和初始状态。 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

scala-lang 论坛中发现了类似的问题并由 Martin Odersky 回答

We had that convention early on in the design of Scala. People found it confusing. That's why we changed to use always extends. The way I see it is like this:

class A extends B with C { ... }

should be decomposed as:

class A extends <<< B with C { ... } >>>

That is, A is a class that extends the anonymous template B with C { ... }. It does not matter whether that template starts with a class or a trait.

Another advantage of the new convention is that subclasses are not affected when a class is changed to a trait or vice versa, something that happens quite often and naturally.

Cheers

-- Martin