Рассмотрим неизменяемый (из-за того, что он является внешней зависимостью, например, от библиотеки) граф объекта, например:
public class A {
private B reference;
private List<C> moreReferences = new ArrayList<>();
public void setReference(B ref) {
reference = ref;
}
public B getReference() {
return reference;
}
public addMoreReference(C ref) {
moreReferences.add(ref);
}
public List<C> getMoreReferences() {
return moreReferences;
}
}
public class B {
private A backlink;
public void setBacklink(A link) {
backlink = link;
}
public A getBacklink() {
return backlink;
}
}
public class C {}
Каковы лучшие практики при попытке расширить все эти классы? Предположим, я создаю подклассы всех трех классов: MyA
, MyB
и MyC
, добавляя ко всем дополнительные методы и поля. Тогда я всегда сталкиваюсь с проблемой, что MyA::getReference()
по-прежнему возвращает экземпляры B
, хотя мне здесь понадобится MyB
. Приведение типов не кажется изящным решением и приводит к проблемам, как только задействуются Коллекции или Обобщения: MyA::getMoreReferences()
не может быть просто приведено из List<C>
в List<MyC>
. Я рассматривал ковариантные возвращаемые типы (переопределение возвращаемого типа метода в моем подклассе), но это также не удается, когда задействованы Generics.
Какие шаблоны или методы рекомендуются в этом случае? Я ищу не столько простое «исправление» для c проблем, сколько универсальный шаблон, на котором будет основана моя иерархия классов.