scala编程-特质用来做可堆叠的改变

特质的一个重要用法是把瘦接口转变成胖接口。

第二个主要用法是为类提供可堆叠的改变,特质让我们改变类的方法,它们能够通过堆叠这些改动的方式做到这点

举个栗子:

整数队列的堆叠改动

队列有两种操作:put,把整数放入队列,和get,从尾部取出它们

队列是先进先出的,因此get应该依整数进入队列时的顺序把他们取出来。

假设,一个类实现了这样的队列,你可以定义特质执行如下的改动:

Doubling:把所有放入到队列的数字加倍

Incrementing:把所有放入到对垒的数字增值

Filtering:从队列中过滤掉负数

这三种特质代表了改动,因为他们改变了原始队列的类的行为而并非定义了全新的队列类。这三种同样也是可堆叠的

//抽象类IntQueue
abstract class IntQueue{
	def get():Int
	def put(x:Int)
}
//使用了ArrayBuffer的IntQueue实现
import scala.collection.mutable.ArrayBuffer

class BasicIntQueue extends IntQueue{
	private val buf = new ArrayBuffer[Int]
	def get() = buf.remove(0)
	def put(x:Int) {buf += x}
}
val queue = new BasicIntQueue
println(queue)
queue.put(10)
queue.put(20)
println(queue.get)
println(queue.get)
//Doubling 特质中定义了超类IntQueue.这个定义意味着特质只能混入扩展了IntQueue的类
trait Doubling extends IntQueue{
	abstract override def put(x: Int) {super.put(2 * x)}
}
//并且这个特质在声明为抽象的方法中有一个super的调用。这种调用对于普通类来说是非法的,
//因为他们在执行时将必然失败。然而对于特质来说,这样的调用实际能够成功。因为特质里的super调用的
//是动态绑定的,特质Doubling的super调用将直到,被混入另一个特质或类之后,有了具体的
//方法定义时才工作
//
//这种安排对于实现可堆叠改动的特质来说是常常要用的到的,为了告诉编译器你的目的,你必须在这种方法打上abstract override的标志,这种标识符的组合仅在特质成员的定义中被认可
class MyQueue extends BasicIntQueue with Doubling
val myqueue = new MyQueue
myqueue.put(30)
println(myqueue.get)


 

你可能感兴趣的:(scala,编程,scala)