I am building a generic Tree
class, which supports inheritance of sub-trees. But I\'ve encountered some problems. Would you please kindly help me?
As I see it, there is no perfect solution to this problem. This is basically due to type erasure. The Erasure of Generic Methods article explains that your addChild(final Tree<? extends Leaf> subTree)
function will become a addChild(final Tree subTree)
function. So, even if you could somehow have a generic parameter <TreeType extends Tree<? extends Leaf>> addChild(final TreeType subTree)
(not valid syntax!) it would be erased to addChild(final Tree subTree)
at compile time. Adding your runtime test will work though, so the edit you made will do the job.
I think what you need is the following
class Tree<LT extends Leaf>{
//have your generic add/delete/traverse methods here.
}
class BlueTree<LT extends Leaf> extends Tree<LT>{
//have your blue tree specific add/delete/traverse methods here.
}
class Leaf {
//have basic data members here
}
class BlueLeaf extends Leaf{
//have blue leaf specific data members here
}
did you try such code?
package trees;
import java.util.ArrayList;
public class Trees {
public static void main(String... args) {
Tree<Leaf, Tree<? extends Leaf, ?>> tree_leaf = new Tree<>();
BlueTree<Leaf, BlueTree<? extends Leaf, ?>> blueTree_leaf = new BlueTree<>();
Tree<RedLeaf, Tree<? extends RedLeaf, ?>> tree_redLeaf = new Tree<>();
BlueTree<RedLeaf, BlueTree<? extends RedLeaf, ?>> blueTree_redLeaf = new BlueTree<>();
//1
tree_leaf.addChild(tree_leaf);
tree_leaf.addChild(tree_redLeaf);
tree_leaf.addChild(blueTree_leaf);
tree_leaf.addChild(blueTree_redLeaf);
//2
tree_redLeaf.addChild(tree_redLeaf);
tree_redLeaf.addChild(blueTree_redLeaf);
tree_redLeaf.addChild(tree_leaf);//compile error
tree_redLeaf.addChild(blueTree_leaf);//compile error
//3
blueTree_leaf.addChild(blueTree_leaf);
blueTree_leaf.addChild(blueTree_redLeaf);
blueTree_leaf.addChild(tree_leaf);//compile error
blueTree_leaf.addChild(tree_redLeaf);//compile error
//4
blueTree_redLeaf.addChild(blueTree_redLeaf);
blueTree_redLeaf.addChild(tree_leaf);//compile error
blueTree_redLeaf.addChild(tree_redLeaf);//compile error
blueTree_redLeaf.addChild(blueTree_leaf);//compile error
}
}
class Tree<Data ,Children extends Tree<? extends Data, ?>> {
//important in this question
private Tree<? super Data, ? super Children> mParent;
private Data mData;
private ArrayList<Children> mChildren;
// This is the focus of this question, the addChild() method signature
public void addChild(final Children subTree) {
// add the subTree to mChildren
}
}
class BlueTree<Data, Children extends BlueTree<? extends Data, ?>> extends Tree<Data, Children> {
}
class Leaf {
}
class RedLeaf extends Leaf {
}