This is a followup to this question. Essentially, I have the following classes:
public class Parent<B> {
public B b;
public Parent(B b) {
this.b = b;
}
}
public class Child<B> extends Parent<B> {
public Child(B b) {
super(b);
}
}
And I'd like to have another class that references them:
public class Foo<ParentType<B> extends Parent<B>, B> {
// ^ syntax error here: > expected
public ParentType<B> parent;
public B otherItem;
public Foo(ParentType<B> parent, B otherItem) {
this.parent = parent;
this.otherItem = otherItem;
B b = parent.b;
}
}
I think it's clear to a human what I think the above should do, but Java basically considers it a syntactic mess, starting with the first nested <
.
I try removing the <B>
part in the class template declaration:
public class Foo<ParentType extends Parent, B> {
public ParentType<B> parent;
// ^ (5:12)
public B otherItem;
public Foo(ParentType<B> parent, B otherItem) {
// ^ same error here
this.parent = parent;
this.otherItem = otherItem;
B b = parent.b;
}
}
but IntelliJ complains
Type 'ParentType' does not have type parameters
and the compiler gives the error:
Error:(5, 12) java: unexpected type
required: class
found: type parameter ParentType
Eventually I can get all the errors to go away if I make the code look like this:
public class Foo<ParentType extends Parent, B> {
public ParentType parent;
public B otherItem;
public Foo(ParentType parent, B otherItem) {
this.parent = parent;
this.otherItem = otherItem;
Object b = parent.b;
}
}
However, this doesn't allow me to ensure that b
is a B
, and I want that to be enforced so that I can pass it to a method that accepts a B
, for instance.
The answer to my previous question was to add more templating, but I have only been able to get the code to compile by removing some. Is there a trick I'm missing?
I'm aware that I can workaround this problem by casting, but I'd like to have a solution enforced by the compiler if at all possible.