線性化

可堆疊修改的情況下,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 

有關線性化的更多資訊,請參見此處