线性化

可堆叠修改的情况下,Scala 以线性顺序排列类和特征以确定方法调用层次结构,这称为线性化。线性化规则用于涉及通过 super() 进行方法调用的那些方法。让我们通过一个例子来考虑这个问题:

class Shape {
  def paint (shape: String): Unit = {
    println(shape)
  }
}

trait Color extends Shape {
  abstract override def paint (shape : String) {
    super.paint(shape + "Color ")
  }
}

trait Blue extends Color {
  abstract override def paint (shape : String) {
    super.paint(shape + "with Blue ")
  }
}

trait Border extends Shape {
  abstract override def paint (shape : String) {
    super.paint(shape + "Border ")
  }
}

trait Dotted extends Border {
  abstract override def paint (shape : String) {
    super.paint(shape + "with Dotted ")
  }
}

class MyShape extends Shape with Dotted with Blue {
  override def paint (shape : String) {
    super.paint(shape)
  }
}

线性化从后到前发生。在这种情况下,

  1. 第一个 Shape 将被线性化,看起来像:

    Shape -> AnyRef -> Any

  2. 然后 Dotted 线性化:

    Dotted -> Border -> Shape -> AnyRef -> Any

  3. 接下来是 Blue。通常 Blue 的线性化将是:

    Blue -> Color -> Shape -> AnyRef -> Any

    因为,到目前为止,在 MyShape 的线性化中( 步骤 2 ),Shape -> AnyRef -> Any 已经出现了。因此,它被忽略了。因此,Blue 线性化将是:

    Blue -> Color -> Dotted -> Border -> Shape -> AnyRef -> Any

  4. 最后,将添加 Circle,最终线性化顺序为:

    圆圈 - >蓝色 - >颜色 - >虚线 - >边框 - >形状 - >任意参考 - >任意

super 用于任何类或特征时,此线性化顺序决定方法的调用顺序。以线性化顺序调用右边的第一个方法实现。如果执行 new MyShape().paint("Circle "),它将打印:

Circle with Blue Color with Dotted Border 

有关线性化的更多信息,请参见此处