Reputation: 1
Possibly a simple question, but I can't seem to do this for some reason. How do I instantiate an object of type BinaryTree from the class below:
public class BinaryTree<N extends BinaryTree.BTNode<N>> {
public static class BTNode<N extends BTNode<N>> {
public N left;
public N right;
public N parent;
}
//some methods which return variables of type N
//or take variables of type N as arguments
}
Both:
BinaryTree<BTNode> tree = new BinaryTree<BTNode>();
and:
BinaryTree<BTNode<BTNode>> tree = new BinaryTree<BTNode<BTNode>>();
generate a compiler error in Eclipse saying the type BTNode is not a valid substitute for the bounded parameter N extends BTNode.
The reason for this structure is that I want to be able to extend BinaryTree and BTNode and have the subclass call superclass functions which return variables of type N, and have N be of the type of the subclass of BTNode, not of type BTNode.
I feel like I may be missing something obvious here, but I've searched extensively and spent a decent amount of time trying different things and I remain unable to do this.
Any help is appreciated.
Upvotes: 0
Views: 261
Reputation: 1
I eventually figured out how to do exactly what I was trying to do, which I thought I would post for posterity's sake.
Basically, I had
Class Node<N extends Node<N, E>, E> {
N left, right, parent;
E element;
and
Class Tree<N extends Node<N, E>, E> {
N rootNode;
N externalNode;
public N findNode(E e) //returns the node with element e
public boolean add(E e) //adds a new node of type N with
// element e to the tree
//etc
The purpose of structuring it like this is so that if it's extended later the subclasses can call superclass methods, including the constructors, and have the right type of N be created or returned. I have a generic node that can be extended, and a generic tree that can be extended, and when using descendants of either I can call the superclasses add(E e) method and be sure the right type of N containing e is created and added, etc...
For example:
Class XNode<N extends XNode<N, E>, E> extends Node<N, E> {
and
Class XTree<N extends XNode<N, E>, E> extends Tree<N, E> {
Anyway, the problem I had is that I couldn't instantiate an object of type Node<N extends Node<N, E> E>
because no matter what I passed as a parameter I was getting the error <parameter> is not a valid substitute for the bounded parameter N extends Node<N, E>, E
.
The solution was to create a class:
Class SampleNode<E> extends Node<SampleNode<E>, E>
I added a field N sample; to the Tree class, and changed the constructor of Tree so that an instance of the sample node type can be passed. Now I can instantiate with:
SampleNode<ElementType> sample = new SampleNode<ElementType>();
Tree<SampleNode<ElementType>, ElementType> tree
= new Tree<SampleNode<ElementType>, ElementType>(sample);
and create new nodes in the tree with:
public N newNode() {
return (N)(sample.getClass().newInstance()) //needs try-catch and
// suppress unchecked
Anyway, I'm not sure if anyone cares, but I thought I'd post the solution anyway.
Upvotes: 0
Reputation: 12932
Not exactly an answer to your problem, but I think your problem is caused by a suboptimal design. Keep your types simple! For a binary tree, I would expect the type parameter to be the type of the data in the tree, i.e. the type of the labels of the nodes. Since you can use type variables as type parameters also, this should be exactly what you want.
public class BinaryTree<E> {
public static class BTNode<T> {
public T label;
public BTNode<T> left;
public BTNode<T> right;
public BTNode<T> parent;
}
//some methods which return variables of type BTNode<E>.
//or take variables of type BTNode<E> as arguments
}
Upvotes: 2