私はグラフのような階層構造でノードのようなオブジェクトを記述するための特性を書いています。私の作業のコードは以下の通りです:ジェネリック特性を拡張するクラスで、パラメータ `this 'を持つメソッドを呼び出すことができないのはなぜですか?
import org.scalatest.FlatSpec
class DummyRoot extends RootNode
class DummyNonRoot(override val parents: List[DummyRoot])
extends NonRootNode(parents)
class TestUtil extends FlatSpec {
"A RootNode" should "not have parents" in {
val dummyRoot = new DummyRoot
assert(dummyRoot.parents.isEmpty)
}
"A NonRootNode" should "have parents when constructed with them" in {
val dummyRoot = new DummyRoot
assert(dummyRoot.parents.isEmpty)
val dummyNonRoot = new DummyNonRoot(List(dummyRoot))
dummyRoot.addChild(dummyNonRoot)
assert(dummyNonRoot.parents.contains(dummyRoot))
assert(dummyRoot.children.contains(dummyNonRoot))
}
}
は、しかし、私は2番目のテストで少し扱いにくいようにAPIを見つける:
trait Hierarchical[T <: Hierarchical[_]] {
// The parents will be a list of some arbitrary Hierarchical
val parents: List[Hierarchical[_]] = Nil
var children: List[Hierarchical[T]] = List()
def addChild(child: Hierarchical[T]): Unit = {
children ++= List(child)
}
}
abstract class NonRootNode(override val parents: List[Hierarchical[_]])
extends Hierarchical[NonRootNode] {
}
abstract class RootNode extends Hierarchical[NonRootNode] {
final override val parents = Nil
}
私はこの動作を反映していくつかのテストを持っています。私は子供の親を既に指定しているので、ルートノードに子を明示的に追加する必要はありません。私はこれを公開APIから削除したいと思いますので、私はNonRootNode
のコンストラクタの動作を変更して、それぞれの親に対して呼び出すことを考えています。具体的には、私が書きたい:私はこの行を追加するとき
abstract class NonRootNode(override val parents: List[Hierarchical[_]])
extends Hierarchical[NonRootNode] {
//for each parent, add `this` to its children
parents.map{p=>p.addChild(this)}
}
しかし、私は次のエラーを取得する:
Error:(19, 29) type mismatch;
found : NonRootNode
required: Hierarchical[_$3]
parents.map{p=>p.addChild(this)}
私はなぜ私はこのコンパイラエラーを取得しています完全にはよく分かりません。 Hierarchical[_]
の私の理解はです。Hierarchical
ですが、間違いかもしれません。いずれにせよ、私は私が望む行動に近いと思う。私は間違って何をしていますか?
子供が階層型[T]である間、両親はどのように '階層型 'になることができますか? –
@ Jasper-M親は 'RootNode'または' NonRootNode'(または 'Hierarchical'の他の拡張子)でもかまいません。子供たちはすべて、それらが「階層的」であるように、同じタイプである。 – erip