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
}

 

posted @ 2020-12-06 11:40  地中有山  阅读(82)  评论(0编辑  收藏  举报