Мне нужно смоделировать узел в дереве. Конечно, у узла есть дочерние элементы, и есть иерархия наследования узлов:
trait Node extends Seq[Node] {
val children:List[Node] = List()
def apply(n:Int) = children(n)
def iterator = children.iterator
def length = children.length
def add(n:Node):Node = { ??? }
}
case class NodeA(n:Int) extends Node
case class NodeB(n:String) extends Node
case class NodeC(c:String) extends NodeB(c)
val na:NodeA = new NodeA(1)
val na1:NodeA = na.add(new NodeB("a"))
na1.children == List(NodeB("a"))
val na2:NodeA = na1.add(new NodeC("b"))
na2.children == List(NodeB("a"), NodeC("b"))
Проблема в том, что я хочу, чтобы Node и его подклассы оставались неизменными.
Вот тогда у меня начнутся проблемы. Как правильно написать метод .add на Node? Поскольку очевидно, что вызов NodeA.add должен возвращать NodeA, а не Node.
Дополнительный ущерб заключается в том, что даже если я добавлю все реализации методов, специфичные для Node (children
, add
, remove
), в каждый из подклассов (или в объекты-компаньоны, компоновщики, CanBuildFrom и т. Д.), Мне потребуется определить children
в качестве параметра конструктора. Что мешало бы определению и использованию подклассов Node - я должен избегать этого, если это возможно.
Возможно ли это? Или я что-то не так делаю и есть другой способ?