I have following code:
interface Id{
int getA();
}
class Id1 implements Id{
@Override
public int getA() {
return 0;
}
}
class Id2 implements Id{
@Override
public int getA() {
return 0;
}
public int getB(){
return 2;
}
}
interface Container<I extends Id, C extends Container<I,C>>{
C withInt(int a);
}
class DefaultContainer<I extends Id> implements Container<I, DefaultContainer<I>>{
@Override
public DefaultContainer<I> withInt(int a) {
return new DefaultContainer<>();
}
}
class SpecialContainer<I extends Id> extends DefaultContainer<I>{
@Override
public SpecialContainer<I> withInt(int a) {
return new SpecialContainer<>();
}
}
interface ContainerGroup<C extends Container<? extends Id, C>>{
Stream<C> getContainers();
}
class DefaultContainerGroup<DC extends DefaultContainer<? extends Id>>
implements ContainerGroup<DC>{
//Error:(36, 35) java: type argument DC is not within bounds of type-variable C
@Override
public Stream<DC> getContainers() {
//can return:
// [ DefaultContainer<Id>, DefaultContainer<Id2>, ... ] OR
// [ SpecialContainer<Id>, SpecialContainer<Id2>, ... ]
return null;
}
}
And the problem is last Error:(36, 35) java: type argument DC is not within bounds of type-variable C.
Inside container group, I can store containers with both type IDs. I assume that there is no better way to store this than ? In runtime, I will have to use instanceof to test for Id1 or Id2 in order to access that getB() getter. If this was behaviour (and not data) I could have common method in Id interface, but since this is data only present in Id2, I suppose downcasting is only way?
UPDATE
Actually this solves the ERROR, but don't know why first solution does not work:
interface ContainerGroup<C extends Container<? extends Id, ? extends Container>>{
Stream<C> getContainers();
}