I want to use a domain specific tree DomainTree
consisting of Domain specific Nodes DomainNode
, but keep all generic functions in template classes Tree
and Node
. First I started with the templates Tree<T>
and Node<T>
(where T is the type of a nodes data). The DomainTree
was then working with the Node<T>
interface, which was not what I wanted. It should work on DomainNode
objects instead.
To cope with that, I changed the generic tree's template parameter to Tree<N extends Node<?>>
(the implementation below). Now I can work with the DomainNode
by instantiating the tree as DomainTree<DomainNode>
.
Still, I get a compilation error at (1) because getChildren()
returns a list of Node<T>
, which doesn't seem to be convertible to a list of N
, though I made sure that N extends Node<?>
.
Why is this not working and how can I design it, so that the DomainTree
can work with DomainNode
s?
Generic Tree
import java.util.ArrayList;
import java.util.List;
class Tree<N extends Node<?>> {
public N rootElement;
public List<N> toList() {
List<N> list = new ArrayList<N>();
walk(rootElement, list);
return list;
}
private void walk(N element, List<N> list) {
list.add(element);
List<N> children = element.getChildren(); // (1) Cannot convert from List<Node<T>> to List<T>
for (N data : children) {
walk(data, list);
}
}
}
class Node<T> {
public T data;
public List<Node<T>> children;
public List<Node<T>> getChildren() {
if (this.children == null) {
return new ArrayList<Node<T>>();
}
return this.children;
}
public void addChild(Node<T> child) {
if (children == null) {
children = new ArrayList<Node<T>>();
}
children.add(child);
}
}
Problemspecific Tree
class DomainTree extends Tree<DomainNode> {
public void build() {
for (DomainNode node : toList()) {
// process...
}
}
}
class DomainNode extends Node<String> {
}