装饰实例的新实例

时间:2011-01-04 15:44:10

标签: scala

我有一组装饰器特征(为简单起见,这里只有特性T)混合在类中(这里是A的子类)。

trait T { def i: Int }
abstract class A
type AT = A with T
class B extends A
// class C extends A
// class D extends A
// ...
现在我有一个例如a的实例我作为B类型的实例处理的类AT(与其他A - 子类 - AT - Seq[AT]中的实例一起处理。
val a: AT = new B with T { val i = 8 }
我怎么能像这样一般装饰:
def toAT(a: A, i: Int): AT = {
 // how to ???
}
我想到的一个明显的解决方案是:
trait T { def i: Int }
abstract class A {
  def asAT(i: Int): AT
}
class B extends A {
  def asAT(ii: Int): AT = new B with T { val i = ii }
}
type AT = A with T
def toAT(a: A, i: Int): AT = a.asAT(i)
但我不想用新方法污染我的类B, C, ..., Z,还有其他装饰,所以对于每个装饰组合我需要一个新方法用于所有子类! 有更通用的方法吗?

编辑: 我需要toAT方法的一个例子,但仍然使用上面明显的解决方法redecorated方法:

trait T { def b: Boolean}
type AT = A with T
abstract class A(val i: Int) {
  def changedBy(x: Int): A
  def redecorated(oldAT: AT): AT
}
class B(x: Int) extends A(x) {
  def changedBy(x: Int): A = new B(i * x) 
  def redecorated(oldAT: AT): AT = new B(i) with T { val b = oldAT.b }
}
class C(x: Int) extends A(x) {
  def changedBy(x: Int): A = new C(i * x * x) 
  def redecorated(oldAT: AT): AT = new C(i) with T { val b = oldAT.b }
}
val b = new B(1) with T { val b = true  }
val c = new C(1) with T { val b = false }
val x = 8
val res: Seq[AT] = Seq(b,c) map { at => at.changedBy(x).redecorated(at) }

1 个答案:

答案 0 :(得分:2)

基本上,你不能这样做。

另一种方法是使用auto proxy pluginKevin Wright。另请参阅herehere以获取有关它的更多信息。