scala如何线性化它?

时间:2018-10-06 20:24:48

标签: scala

我正在通过Scala的Odersky编程进行工作,并且正在查看有关特征的章节。他举了一个示例,其中将各种特征/类线性化并说:

Cat -> FourLegged -> HasLegs -> Furry -> Animal -> AnyRef -> Any
  

当这些类和特征中的任何一个通过super调用方法时,       调用的实现将是其右侧的第一个实现       线性化。

我对类/特征的定义如下:

abstract class Animal { def hi }

class Cat extends Animal { def hi { println("cat") } }

trait Furry extends Animal { abstract override def hi { 
  println("furry"); super.hi } } 

完成

val c = new Cat with Furry
c.hi

我明白了

furry
cat

根据这本书,毛茸茸的超级人应该调用Animal.hi,因为Animal是抽象的,因此应该会导致编译错误或运行时错误。相反,它调用cat.hi我想念什么?我以为Cat类会在线性化过程中首先出现,因此super调用无法调用它吗?

(为了简化起见,我错过了HasLegs和FourLegged)

我怀疑他们误解了线性化顺序?

谢谢!

编辑:在下面user2357112的评论之后,我尝试静态混合Furry特性:

scala> class Cat extends Animal with Furry { def hi { println("cat") } }
<console>:13: error: overriding method hi in trait Furry of type => Unit;
 method hi needs `override' modifier
       class Cat extends Animal with Furry { def hi { println("cat") } }

我现在很困惑,因为我认为无论是在运行时还是在代码中混入特质都没有什么不同。但是在这里,运行时mixin的执行没有错误,但是如果尝试将其混入代码中,则会出现编译错误。是什么赋予了?

1 个答案:

答案 0 :(得分:0)

根据this answer,使用mixin时将首先构造具体类,而线性化顺序与构造顺序相反。因此,构造为Animal -> Cat -> Furry,线性化为Furry -> Cat -> Animal,这就是为什么您首先看到“毛茸茸”而第二看到“猫”的原因。