Я думаю, что я слишком усложнил свой дизайн дженериков в своем приложении (собираюсь попытаться упростить его), но независимо от того, хочу ли я посмотреть, возможно ли это.
Допустим, есть следующие классы (это дизайн моей трехслойной иерархии в моем приложении):
abstract class A<T extends A<T>> // LAYER 1
abstract class B<T extends B<T>> extends A<T> // LAYER 2
class C extends B<C> // LAYER 3
Первый уровень (класс A) обеспечивает классы B и C, расположенные на 2-м или 3-м уровне, расширяют класс A насам тип (B и C, соответственно).
Второй уровень (класс B) гарантирует, что класс C, расположенный на 3-м уровне, расширяет класс B типом C и расширяет класс A типом C (таким образомнаследование от обоих).
Третий слой удовлетворяет контракту первых двух слоев.
Теперь у меня есть еще один класс, следующий:
class D<T extends A<T>>
Я хочу, чтобы T
был либо A
, B
, либо C
.Я пробовал следующие три:
new D<A<?>> or new D<A> // not allowed, A must extend A<A>
new D<B<?>> or new D<B> // not allowed, B must extend A<B> (it extends A<?>)
new D<C> // allowed
Есть ли простые изменения, которые я могу внести в свой дизайн, чтобы разрешить первые два?
Вот пример того, почему мне нужна эта функциональность:
List<? extends B<?>> list = ...; // a list containing subclasses of B
for (B<?> item : list) {
D<B<?>> result = new D<B<?>>(item); // not allowed
}