How do I subclass a list element declared in my interface?
In a current project, we’re looking at our strong types having both interfaces and concrete implementations. There’s a reason for this that’s NOT about making things mockable.
Read More: 1Z0-816: Oracle Java SE 11 Programmer II
What’s nice and obvious is that this is possible:
public interface Bar {
}
public interface Foo {
Bar getBar();
}
public class BarImpl implements Bar {
}
public class FooImpl implements Foo {
public BarImpl getBar() { ... }
}
Despite the fact that the FooImpl subclass returns a subclass of the interface’s declared getter everything compiles happily, because a subclass can be substituted for a base class and still meet the Liskov substitution principle.
However, there’s a problem if you try to do this:
public interface Foo {
List<Bar> getBars();
}
public class FooImpl implements Foo {
// compiler error...
public List<BarImpl> getBars() { ... }
}
In the Java generic type system, List<BarImpl> is not a subclass of List<Bar>. The folks who designed this stuff are pretty clever, and there’s probably a very good technical reason why this is the case.
The question is – can it be solved?
public interface Foo<T extends Bar> {
// we know this is "at least" a Bar
List<T> getBars();
}
public class FooImpl implements Foo<BarImpl> {
// compiles great
public List<BarImpl> getBars() { ... }
}
For lots of List or Optional of things, this might seem a bit cumbersome, but it is how it’s done… apparently.
Source: javacodegeeks.com
0 comments:
Post a Comment