Допустим, у меня есть эти два иерархий наследования:Java параллельно иерархий наследования родовых типов и ковариант- возвращает
class EntityA { ... }
class EntityB extends EntityA { ... }
class EntityAPrime extends AbstractPrime<EntityA> { ... }
class EntityBPrime extends EntityAPrime { ... }
Я также хотел бы ковариантных типов возврата:
public class EntityA {
public EntityAPrime prime() {
return new EntityAPrime();
}
}
public class EntityB extends EntityA {
@Override
public EntityBPrime prime() {
return new EntityBPrime();
}
}
до сих пор так хорошо.
Проблема в том, что я хотел EntityBPrime
, чтобы в конечном итоге расширить AbstractPrime<EntityB>
, но так как он расширяет EntityAPrime
это в конечном счете расширяет AbstractPrime<EntityA>
.
я могу сделать EntityAPrime
и EntityBPrime
универсальна, но тогда я потеряю ковариантные возвращаемые типы:
public class EntityA {
public EntityAPrime<EntityA> prime() {
return new EntityAPrime();
}
}
public class EntityB extends EntityA {
@Override
public EntityBPrime<B> prime() { // ERROR: EntityBPrime extends EntityAPrime
return new EntityBPrime(); // but can't substitute <EntityB> for <EntityA>
}
}
Все работает, если я возвращаю связанный подстановочные но есть disadvantages, связанные с этим, и я не смог бы назвать конкретный сеттер на AbstractPrime
.
Еще одна идея, которую я имел, состоит в том, чтобы сделать EntityA
и EntityB
самим общим.
public class EntityA<T extends EntityA> {
public EntityAPrime<T> prime() { ... }
}
public class EntityB<T extends EntityB> extends EntityA<T> {
@Override
public EntityBPrime<T> prime() { ... }
}
Это должно работать, но я думаю, что это будет запутаться (у нас есть более 100 объектов, которые могли бы использовать подобный рисунок).
Итак, есть ли способ:
- держать общековариантные возвращается
- не использовать дженерики на
EntityA
иEntityB
- не
prime()
вернуть связанного WildCard - и имеют
EntityBPrime
в конечном счете продлитьAbstractPrime<EntityB>
вместоAbstractPrime<EntityA>
Примечание: простые классы - это сгенерированный код, но у меня есть контроль над кодом, который генерирует.
Нет, если вы не нарушаете наследование между A и B. Можете ли вы использовать композицию вместо этого? –
@EricStein Объекты были смоделированы с учетом наследования и сопоставлены с таблицами таким образом. Хотя это действительно хорошо. –
Я думаю, что ты за рулем. Расширение снова наносит удар. :-( –