Scala 如何抽象地扩展一个路径依赖的特征:“;超越特质;?
对于路径依赖特性,如何为特定的封闭对象指定该特性必须支持其他特性<代码>覆盖特性?你是如何引用这个子序列延伸的原始特征的 具体来说,我想覆盖每个Scala 如何抽象地扩展一个路径依赖的特征:“;超越特质;?,scala,overriding,traits,path-dependent-type,Scala,Overriding,Traits,Path Dependent Type,对于路径依赖特性,如何为特定的封闭对象指定该特性必须支持其他特性覆盖特性?你是如何引用这个子序列延伸的原始特征的 具体来说,我想覆盖每个DeltaSet对象中的Delta特征: trait DeltaSet { type PertainsTo trait Delta { val pertainsTo: PertainsTo } . . . } 在英语中,这是“同一DeltaSet中的每个Delta都必须属于同一类事物。” DeltaSet对象应该能够向Delta特征添
DeltaSet
对象中的Delta
特征:
trait DeltaSet {
type PertainsTo
trait Delta {
val pertainsTo: PertainsTo
}
. . .
}
在英语中,这是“同一DeltaSet
中的每个Delta
都必须属于同一类事物。”
DeltaSet
对象应该能够向Delta
特征添加更多属性,如source
此处:
val deltaSet = new DeltaSet {
override type PertainsTo = UnorderedPair[TestNode]
override trait Delta /* extends DeltaSet.Delta?? */ { // <-- THE MYSTERY
val source: TestNode
}
. . .
}
对于BreakLinkDelta
和其他delta
而言,对于deltaSet
也是如此。(此Delta集的每个Delta
描述了对图形所做的更改。其他Delta集包含对完全不同类型对象的更改。)
我尝试了很多变体,包括trait BaseDelta{…};键入DeltaTExtendDeltaSet
及其Delta
添加source
属性:
trait DeltaSetTN extends DeltaSet {
override type PertainsTo = UnorderedPair[TestNode]
trait DeltaTN extends Delta {
val source: TestNode
}
}
然后:
您可能会对Scala中的依赖项注入和cake模式感兴趣。这可以:
(1) 在封闭的trait中定义一个basetrait
,并将其作为抽象类型的上限
(2) 使用object
语句而不是val
语句创建容器对象
(3) 在对象
上放置一个类重写,用与抽象类型
相同的名称定义封闭的特征
。此定义必须扩展基本的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...
. . .
}
我猜object
编译失败和val
失败的原因是val
没有定义名称空间,我们需要一个名称空间来引用封闭的、被覆盖的Delta
特征,当我们在这里将其子类化时:
case class MakeLinkDelta(fromNode: TestNode, toNode: TestNode)
extends deltaSet.Delta // Since deltaSet is a namespace, the dot syntax can refer
{ // to the Delta trait inside it.
override val pertainsTo = new UnorderedPair(fromNode, toNode)
override val source = fromNode
. . .
}
(最后一部分与问题中的代码相同。)您能在此解释相关的工作原理吗?“不能在匿名类中重写路径依赖特征”?“你不能在任何地方覆盖路径依赖特征”?“每个路径相关(Delta
)对象必须扩展容器(DeltaSet
)特性”?我希望最后一个不是真正的原则。我们不能忽略一个特征。为此,我们扩展并覆盖其成员。我不太明白你的最后一点。一个特征在实例化时不能保持为一个特征。谢谢你的“我们不能覆盖一个特征。”(也许这可以作为答案。)澄清最后一点:在您的解决方案中,Delta
类扩展了DeltaSet
的特性。这对我来说似乎很奇怪,就像说杯子是一种橱柜。有什么Scala原则需要这样做吗?我将把问题中的MakeLinkDelta
改为DeltaForLink
,因为“Make”可能会引起混淆。非常好。:)我想我会切换回MakeLinkDelta
,并提到一个对比鲜明的BreakLinkDelta
。这应该可以澄清,对于一个DeltaSet
,可以有许多Delta
类(并且需要较少的编辑)。
trait DeltaSet {
type PertainsTo
trait BaseDelta {
val pertainsTo: PertainsTo
}
type Delta <: BaseDelta // <-- Since this is now a type, we can override it...
. . .
}
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.
}
. . .
}
case class MakeLinkDelta(fromNode: TestNode, toNode: TestNode)
extends deltaSet.Delta // Since deltaSet is a namespace, the dot syntax can refer
{ // to the Delta trait inside it.
override val pertainsTo = new UnorderedPair(fromNode, toNode)
override val source = fromNode
. . .
}