I have the following structure. A parent class:
public class MyTree<E extends MyTree<E>>{
List<E> children;
public MyTree(List<E> ls){
this.children = ls;
}
public void insert(E t){
this.children.add(t);
}
}
a child class:
public class SpecTree<E> extends MyTree<SpecTree<E>>{
private E value;
public SpecTree(E value){
super(new ArrayList<>());
this.value = value;
}
}
Now from main, I want to insert a tree into another tree.
SpecTree<Number> st = new SpecTree<>(0);
st.insert(new SpecTree<Integer>(2)); //incompatible type error
The SpecTree
must be able to accept new children with values that are subtype of the current tree. For example, I should be able to insert a SpecTree<Integer>
into SpecTree<Number>
.
Is it possible to do without changing the structure of code and changing only the type parameters?
CodePudding user response:
The error occurs because insert
expects SpecTree<Number>
, but we are giving it SpecTree<Integer>
.
According to PECS, insert
would be able to take both SpecTree<Number>
and SpecTree<Integer>
if it had took a SpecTree<? extends Number>
. A producer of integers is a consumer of numbers.
That means changing E
to SpecTree<? extends E>
:
public void insert(E t)
Therefore:
class SpecTree<E> extends MyTree<SpecTree<? extends E>>
However, now the type argument SpecTree<? extends E>
does not fit the bound specified in MyTree
, which is E extends MyTree<T>
, so we change that too:
class MyTree<E extends MyTree<? extends E>>