Reputation: 213
I have a generic interface A<T>
, I have a class B that implements A<String>
. I've created a class C
that extends B
and implements A<Number>
.
For C
, I get a compile error saying:
A cannot be inherited with different type arguments <String> and <Number>.
Why is this not allowed? If the answer to this is type erasure , then please explain in detail.
Sample code:
public interface A<T> {
}
public class B implements A<String> {
}
public class C extends B implements A<Number> {
}
Upvotes: 2
Views: 2115
Reputation: 1288
The Java Language Specification in §8.1.5 states the following:
A class may not at the same time be a subtype of two interface types which are different parameterizations of the same generic interface (§9.1.2), or a subtype of a parameterization of a generic interface and a raw type naming that same generic interface, or a compile-time error occurs.
This requirement was introduced in order to support translation by type erasure (§4.6).
It means that after erasure your class can end up with methods (if it has any) with the same signature. Refer to Angelika Langer's site for more details.
Upvotes: 3
Reputation: 106400
It wouldn't make sense if you could, honestly.
Here's the scenario:
B
implements A
and binds A<T>
to A<String>
.C
inherits from B
(which is already bound to A<String>
), and you're trying to also implement A<Number>
.You can't have a type implemented both ways.
If you want to incorporate Number
somehow into C
, then you'll have to have the type on C
and not just on A
.
This will compile but it will look strange:
public class C<T> extends B implements A<String> {
}
Ultimately this really boils down to how your hierarchy needs to be laid out. If you really need a relationship between B
and C
, then it doesn't make sense to concrete their types in this way; just have them use T
as the generic instead. Finally, by virtue of inheritance, you still have access to the general contract of A
through B
in C
, so you do not need to implement it.
public interface A<T> {
}
public class B<T> implements A<T> {
}
public class C<T> extends B<T> {
}
Upvotes: 4