如何抽象地扩展依赖于路径的特征:“覆盖特征”?

时间:2015-07-05 12:32:37

标签: scala override traits path-dependent-type

使用与路径相关的特征,如何为特定的封闭对象指定此特征必须支持其他特征? override trait?你如何引用子标准扩展的原始特征?

具体来说,我想覆盖每个Delta对象中的DeltaSet特征:

trait DeltaSet {
  type PertainsTo

  trait Delta {
    val pertainsTo: PertainsTo
  }
  . . .
}

在英语中,“同一Delta中的每个DeltaSet都必须属于同一类事物。”

DeltaSet对象应该能够为Delta特征添加更多属性,例如source

val deltaSet = new DeltaSet {
  override type PertainsTo = UnorderedPair[TestNode]

  override trait Delta /* extends DeltaSet.Delta?? */ {  // <-- THE MYSTERY
    val source: TestNode
  }
  . . .
}

在英语中,“Delta的每个deltaSet也必须提供来源。”

因此,与Delta对象一起使用的DeltaSet类必须覆盖source属性,如下所示:

case class MakeLinkDelta(fromNode: TestNode, toNode: TestNode)
  extends deltaSet.Delta
{
  override val pertainsTo = new UnorderedPair(fromNode, toNode)
  override val source = fromNode
  . . .
}

以及BreakLinkDeltaDeltas的其他deltaSet类似。 (此Delta的每个DeltaSet描述了对图表所做的更改。其他DeltaSet包含对完全不同类型对象的更改。)

我尝试了很多变种,包括trait BaseDelta {...}; type DeltaT <: BaseDelta,到目前为止还没有编译过。你如何在Scala中“说”,“对于这一个DeltaSet,我想要求每个Delta提供source属性?”

2 个答案:

答案 0 :(得分:2)

这有效:

(1)在封闭特征中定义基础trait,并使其成为抽象type的上限。

(2)使用object语句创建容器对象,而不是val语句。

(3)在object上放置一个类覆盖,定义括号trait,其名称与摘要type相同。此定义必须扩展基础trait,并且必须具有override关键字。

这里的(1),附带特征:

trait DeltaSet {
  type PertainsTo

  trait BaseDelta {
    val pertainsTo: PertainsTo
  }

  type Delta <: BaseDelta          // <-- Since this is now a type, we can override it...
  . . .
}

这是(2),定义具体object的{​​{1}},以及(3)定义DeltaSet的类覆盖:

Delta

我猜测object deltaSet extends DeltaSet { override type PertainsTo = UnorderedPair[TestNode] trait Delta extends BaseDelta { // ...except we don't override, we just define a trait val source: TestNode // with the same name as the abstract type. } . . . } 编译和object失败的原因是因为val没有定义命名空间,我们需要一个命名空间才能当我们在这里继承它时,请参考包含的,重写的val特征:

Delta

(最后一部分与问题中的代码相同。)

答案 1 :(得分:0)

扩展DeltaSet及其Delta添加source属性:

trait DeltaSetTN extends DeltaSet {
  override type PertainsTo = UnorderedPair[TestNode]
  trait DeltaTN extends Delta {
    val source: TestNode
  }
}

然后:

class MakeLinkDelta(fromNode: TestNode, toNode: TestNode) extends DeltaSetTN {
  val delta = new DeltaTNImpl()
  class DeltaTNImpl extends DeltaTN {
    override val source = fromNode
    override val pertainsTo = new UnorderedPair[TestNode](fromNode, toNode)
  }
}

您可能对此blog post感兴趣,了解Scala中的依赖注入和蛋糕模式。