This works :
public interface A {
A doSomething();
}
public interface B extends A{
B doSomething();
}
This doesn't :
public interface A {
Collection<A> doSomething();
}
public interface B extends A{
Collection<B> doSomething();
}
Why? and what can I do to get the functionality I want in the second example?
The reason is that Collection<B>
is not a sub-type of Collection<A>
.
Not every operation that's possible with a Collection<A>
is also possible with a Collection<B>
. Case in point: calling add(new A())
works with a Collection<A>
but must fail with a Collection<B>
(even if that's just checked at compile-time).
If you don't care about adding elements to the returned Collection
(often you only care about iterating over them, effectively treating them as if they were read-only), then you can do this:
public interface A {
Collection<? extends A> doSomething();
}
public interface B extends A{
Collection<? extends B> doSomething();
}
You can even let B.doSomething()
return a Collection<B>
if you want, but then you won't be able to extend B
in the same way again.
Change it to:
public interface A {
Collection<? extends A> doSomething();
}
public interface B extends A{
Collection<B> doSomething();
}
and it'll work properly.
It's because "a collection of B" does not extend a collection of A", even though B extends A. A needs to define the return type as a "collection of items that extends A" than you can narrow it further as "a collection of B". Confusing, yes ... but that's just how it is.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With