views:

48

answers:

2

I am working with tree's in java and I have the following interface for a simple unordered tree with a self reference:

public interface Node<N extends Node> {

  public N getParent();
  public void setParent(N parent);

  public Collection<N> getChildren();

  public void addChild(N node);
  public void removeChild(N node);

  public N getRootNode();

  ... more ...
}

The idea of course is to create a typesafe Node

  public abstract class ParentChildNode<E extends Node> implements Node<E> {

problem that really annoys me is the warning i get:

ParentChild is a raw type. References to generic type Node<N> should be parameterized

warning on this line:

public interface Node<N extends Node> {

warning on this line:

    public abstract class ParentChildNode<E extends ParentChild> implements ParentChild<E>  

I can do:

public interface Node<N extends Node<?>> {

but i fear im treading into yuckness territory. i can suppress the warning but thats not allowed where i work.

any suggestions? I noticed java.util collections API does not have any warnings anywhere.

thanks in advance

+1  A: 

Your type is infinitely recursive. All of your nodes are really of type Node<Node<Node<Node<…>>>> or some equally infinite subtype. Java's generics are simply not sufficiently powerful to handle such things.

Moreover, if you have a tree of these nodes, what's the type of the root? It doesn't have a parent. I suppose you could have a type NullNode<GodKnowsWhat>, but that's merely putting off the problem. I suppose the root could simply return null as a parent, but that's subverting the whole hierarchy.

What you could have instead: I got this far:

public interface Node {
    public Collection<ChildNode<Node>> getChildren();

    public void addChild(ChildNode<Node> node);
    public void removeChild(ChildNode<Node> node);
}

public interface ChildNode<Parent> extends Node {
    public Parent getParent();
    public void setParent(Parent parent);
}

But the type of Node's methods are wrong. You just can't do this in Java. If you'd really like to, try Scala. It runs on the JVM and it's type system is far more sophisticated; I'm fairly certain that it would allow the kind of type recursion you'd need. In addition, you may be able to pull it off in C++. C++ also has a far more powerful type system, but I haven't worked with it enough to know whether it will let you do this kind of thing in more or less these terms.

Thom Smith
+3  A: 

how about something like this (paralleling the declaration of the Enum class):

public interface Node<N extends Node<N>> {

  public N getParent();
  public void setParent(N parent);

  public Collection<N> getChildren();

  public void addChild(N node);
  public void removeChild(N node);

  public N getRootNode();

  ... more ...
}

public abstract class ParentChildNode implements Node<ParentChildNode> {
newacct