2

I'm writing a generic class:

public class Node<T> {
    private Node<T> parent = null;
    private List<? extends Node<T>> children = null;

    public Node<T> getParent() {
        return parent;
    }

    public void setParent(Node<T> parent) {
        if(this.parent != null){
            // Remove current parent's children references
            this.parent.getChildren().remove(this);
        }

        // Add references
        this.parent = parent;
        parent.getChildren().add(this);
    }

    public List<? extends Node<T>> getChildren() {
        return children;
    }
}

I want some other class which subclass this Node. This code cannot be compiled with the error on line parent.getChildren().add(this);. Because I declared getChildren() with List<? extends Node<T>> as return type, and 'this' is type Node<T>.

Is there anyway to solve this?

Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287
Lingfeng Xiong
  • 1,131
  • 2
  • 9
  • 25

1 Answers1

1

Declare the list as:

List<Node<T>> children

You may still put instances of subclasses in the list.

If you leave it as an unknown type, the compiler can't ensure which class it is typed as. Eg it might be typed as SubClassA, but you're adding SubClassB and it has no way to know based on the declared type, which is all the compiler has to go on. At runtime, while the type of list and child might match, the compiler can't assert.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • Change the declaration of 'children' to List> is a way, but actually I need to run some subclass-specified method on it, like: children.get(0).encode("abcdaaaa"). If I changed the declaration, I have to cast it and I don't think it's a good way. :-) – Lingfeng Xiong Sep 22 '13 at 01:08
  • I don't think there's a way around casting – Bohemian Sep 22 '13 at 01:17