Ассоциация, агрегация и композиция в Java - Вопросы

Всего: 5 вопросов

1. 

Чем агрегация отличается от композиции?

Оба отношения описывают связь «часть—целое», но различаются силой связи и жизненным циклом части. При агрегации часть создаётся внешним кодом и передаётся целому (в конструктор или сеттер), может принадлежать нескольким целым и продолжает существовать после исчезновения целого: new PC(keyboard), отдел и сотрудники. При композиции часть создаёт само целое внутри своего конструктора, часть принадлежит только ему и умирает вместе с ним: this.keyboard = new Keyboard(), дом и комнаты. В UML агрегация — незакрашенный (белый) ромб у целого, композиция — закрашенный (чёрный).

2. 

Что такое отношения IS-A и HAS-A между классами в Java?

IS-A («является») основано на наследовании классов или реализации интерфейсов: class Lorry extends Car означает Lorry IS-A Car, а class Transport implements MoveableTransport IS-A Moveable. Проверить IS-A в коде можно оператором instanceof. HAS-A («имеет») основано на использовании: один класс хранит ссылку на объект другого класса в поле — class Car { Engine engine; } означает Car HAS-A Engine. Ассоциация, агрегация и композиция — это уточнения HAS-A.

3. 

Что такое ассоциация и какие у неё бывают направленность и кратность?

Ассоциация — зонтичный термин для связи, при которой объекты двух классов могут ссылаться друг на друга: class Person { private Car car; }. Агрегация и композиция — её частные случаи. По направленности ассоциация бывает односторонней (о другом классе знает только один) и двусторонней (оба хранят ссылки друг на друга). По кратности — один к одному (человек и его автомобиль), один ко многим (магазин и категории), многие ко многим (студенты и курсы); сторона «ко многим» выражается коллекцией или массивом. Двустороннюю связь нужно обновлять одним методом сразу с обеих сторон, иначе данные рассогласуются, а в toString() или equals() может возникнуть бесконечная рекурсия.

4. 

Почему в проектировании предпочитают композицию наследованию (composition over inheritance)?

Правило сформулировано в книге «Приёмы объектно-ориентированного проектирования» (банда четырёх) и повторено Джошуа Блохом в Effective Java. Избыточное наследование делает код хрупким (изменение базового класса ломает наследников), нарушает инкапсуляцию (подкласс зависит от деталей реализации родителя), даёт жёсткую иерархию, зафиксированную на этапе компиляции, и упирается в запрет множественного наследования. Композиция гибче: вместо class Driver extends Employee лучше дать сотруднику поле private Role role — роль можно сменить в любой момент через сеттер. Наследование оправдано, только если подкласс является полноценной заменой родителя (принцип подстановки Лисков) и вы контролируете оба класса.

5. 

Что такое зависимость (dependency) и как виды связей выстраиваются по силе?

Зависимость — самая слабая связь: класс не хранит объект в поле, а получает его как параметр метода, создаёт локально или возвращает из метода, поэтому связь живёт только на время вызова. Пример: void print(Printer printer) в классе ReportService без поля типа Printer. По возрастанию силы связи отношения выстраиваются так: зависимость → ассоциация → агрегация → композиция → наследование. Чем связь сильнее, тем труднее менять классы независимо друг от друга, поэтому в проектировании стремятся к слабой связанности.

Страница 1 из 1