我一直在阅读Programming Scala一书(由Martin Odersky,Lex Spoon,Bill Venners编辑1)并且遇到了特征。我觉得有趣的部分是可堆叠的修改。使用的示例是
abstract class IntQueue {
def get(): Int
def put(x: Int)
}
trait Incrementing extends IntQueue {
abstract override def put(x: Int) {super.put(x+1)}
}
trait Filtering extends IntQueue{
abstract override def put(x: Int){
if(x >=0) super.put(x)
}
}
所以提供的示例有一个具体的类“BasicIntQueue,它扩展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}
}
scala> val queue = (new BasicIntQueue with Incrementing with Filtering)
scala> queue.put(-1);queue.put(0);queue.put(1)
scala> queue.get() = 1
因此,该示例显示过滤和递增都是“链接”并在元素“放入”队列之前执行。
我只是想知道如何在Groovy中实现这一点。由于Groovy的元可编程性,可能不需要它。
答案 0 :(得分:3)
从Groovy 2.3开始,Groovy支持traits和stackable traits。因此,实现与Scala完全相同:
interface IntQueue {
Integer get()
void put(Integer x)
}
trait Incrementing implements IntQueue {
void put(Integer x) { super.put(x+1) }
}
trait Filtering implements IntQueue {
void put(Integer x) { if(x >= 0) super.put(x) }
}
class BasicIntQueue implements IntQueue {
private buf = new ArrayList<Integer>()
Integer get() { buf.remove(0) }
void put(Integer x) { buf << x}
String toString() { buf.toString() }
}
def queue = new BasicIntQueue().withTraits Incrementing, Filtering
queue.put(-1)
queue.put(0)
queue.put(1)
assert queue.get() == 1
答案 1 :(得分:2)
Groovy没有自然的方法来做可堆叠的特性。类别提供了一些特征功能,但它们不适合覆盖方法,并且在没有太多元类魔法的情况下无法堆叠。
groovy中更好的方法是应用装饰器模式和@Delegate
注释。每个“特征”都可以覆盖适当的行为并委托给“超级”类。例如:
interface IntQueue {
def get()
def put(x)
}
class Incrementing implements IntQueue {
@Delegate IntQueue self
def put(x) {
self.put(x+1)
}
}
class Filtering implements IntQueue {
@Delegate IntQueue self
def put(x) {
if (x >= 0) {
self.put(x)
}
}
}
class BasicIntQueue implements IntQueue {
private buf = []
def get() { buf.pop() }
def put(x) { buf << x }
}
然后你可以构造一个具有所需特征的对象,如下所示:
def q = new Filtering(self: new Incrementing(self: new BasicIntQueue()))