Есть две важные вещи, которые вы должны рассмотреть из своего сценария:
1) Поля не могут быть переопределены подклассами. Это не ограничение языка (Java), а концептуальное наложение, которое является разумным. Поля определяют, что объект является , а методы определяют, что объект делает и как . Единственное, что вы можете переопределить, это как вещи выполняются вашими объектами, но вы не можете изменять то, что ваш суперкласс является или делает . (Я говорю «объекты», но имейте в виду, что я имею в виду «экземпляры класса», поскольку вы фактически определяете поведение в теле класса).
2) Вы должны сделать Отношение первоклассным объектом. Поскольку недостаточно использовать то, что дает вам парадигма: «есть» и «имеет». Как заявил Даррен Берджесс, парадигма предоставляет вам два концептуальных отношения: «есть» и «имеет». Например, Человек-> Мужчина или Человек-> Женщина , вы можете использовать наследование, другими словами, "это". Класс Man расширяет Человек, потому что Человек - это Человек . Сложность заключается в отношении «имеет», поскольку ООП не позволяет вам указать количество элементов, а также вы хотите указать имя в отношении. Для простоты давайте определим отношения как двоичные. Например, У мужчины есть жена или у женщины есть муж . Для отношений Джон - отец Тома и Линды , мы определим два отношения: Джон - отец Тома и Джон - отец Линды . Проблема с вашим подходом заключается в том, что вы указали Список мужчин и Список женщин. Однако то, что на самом деле есть у Человека, это Коллекция Отношений . Дизайн будет выглядеть так:
public Human {
private Collection<Relationship> relationships;
}
public Relationship {
private Human party; // We are defining only relationships between humans.
private Human counterparty;
private String name; // e.g., "is the Husband of" and "is the Wife of".
}
Сторона и контрагент являются членами отношений, и экземпляр объекта Relationship будет представлять, как один относится к другому.
Определение конкретного поведения было бы более ad-hor. Например, SociallyPathologicalMale не будет иметь Relationship . Вы можете добавить следующий метод к Human :
public void addRelationship(Relationship newRelationship) {
relationships.add(newRelationship);
}
Класс SociallyPathologicalMale (который расширяет Male) унаследует этот метод и переопределит его следующим образом:
public void addRelationship (Отношение newRelationship) {
// Здесь нечего делать. }
По сути, поскольку SociallyPathologicalMale по определению не может иметь никаких отношений, вы программно отключаете возможность, предоставляемую суперклассом Male .
Надеюсь, это прояснит ваш вопрос.