1. 程式人生 > 實用技巧 >12-5 作為可疊加修改的特質

12-5 作為可疊加修改的特質

定義一個抽象的IntQueue類

abstract class IntQueue {
  def get(): Int
  def put(x: Int)
}

IntQueue的基本實現BasicIntQueue

class BasicIntQueue extends IntQueue {
  private val buf = new ArrayBuffer[Int]

  override def get(): Int = buf.remove(0)

  override def put(x: Int): Unit = buf += x
}

特質Doubling:將所有放入佇列的整數翻倍

①extends IntQueue 這個宣告意味著這個特質只能被混入同樣繼承自IntQueue的類。

②super 由於特質中的super呼叫是動態繫結的,只要在給出了該方法具體定義的特質或類之後混入,Doubling特質裡的super呼叫就可以正常工作。

③abstract override 這樣的修飾符組合只允許用在特質的成員上,不允許用在類的成員上,它的含義是該特質必須混入某個擁有該方法具體定義的類中。

trait Doubling extends IntQueue{
  abstract override def put(x: Int): Unit = super.put(2 * x)
}

特質Incrementing:將所有放入佇列的整數加一

trait Incrementing extends IntQueue {
  abstract override def put(x: Int): Unit = super.put(x + 1)
}

特質Filtering:從佇列中去除負整數

trait Filtering extends IntQueue {
  abstract override def put(x: Int): Unit = if (x >=0) super.put(x)
}

測試1:粗略地講,越靠右出現的特質越先起作用,如果那個方法呼叫super,它將呼叫左側緊挨著它的那個特質的方法,以此類推。在下面的程式碼中,先呼叫Filtering的put最先被呼叫,所以它首先過濾掉了那些負的整數。Incrementing的put排在第二,因此它做的事情就是在Filtering的基礎上對剩下的整數加1

def main(args: Array[String]): Unit = {
  val queue = new BasicIntQueue with Incrementing with Filtering
  queue.put(-1)
  queue.put(0)
  queue.put(1)
  println(queue.get()) //1
  println(queue.get()) //2
}

測試2:與測試1的特質混入順序相反

def main(args: Array[String]): Unit = {
  val queue = new BasicIntQueue with Filtering with Incrementing
  queue.put(-1)
  queue.put(0)
  queue.put(1)
  println(queue.get()) //0
  println(queue.get()) //1
  println(queue.get()) //2
}