Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Агрегация в Java: полное объяснение с примерами
Агрегация - один из ключевых концепций объектно-ориентированного программирования. Давайте разберёмся, что это такое и когда её использовать.
Что такое агрегация?
Агрегация (aggregation) - это отношение типа "часть-целое", где одна сущность (целое) содержит или использует другую сущность (часть). При этом часть может существовать независимо от целого.
Это слабая форма связи между классами, в отличие от композиции, где часть не может существовать без целого.
Ключевое отличие: агрегация vs композиция
Агрегация - слабая связь. Часть может существовать отдельно:
- Университет содержит студентов
- Если университет закроется, студенты будут жить дальше
- Студент может найти другой университет
Композиция - сильная связь. Часть зависит от целого:
- Дом содержит комнаты
- Если дом снесён, комнаты прекращают существование
- Комната не может существовать без дома
Практический пример: Компания и Сотрудники
// Класс сотрудника
public class Employee {
private String id;
private String name;
private String position;
private double salary;
public Employee(String id, String name, String position, double salary) {
this.id = id;
this.name = name;
this.position = position;
this.salary = salary;
}
public String getId() { return id; }
public String getName() { return name; }
public String getPosition() { return position; }
public double getSalary() { return salary; }
}
// Класс компании - ЦЕЛОЕ
// Содержит сотрудников - ЧАСТИ
public class Company {
private String name;
private List<Employee> employees; // Агрегация
public Company(String name) {
this.name = name;
this.employees = new ArrayList<>();
}
// Добавить сотрудника
public void hireEmployee(Employee employee) {
employees.add(employee);
}
// Уволить сотрудника
public void fireEmployee(String employeeId) {
employees.removeIf(e -> e.getId().equals(employeeId));
}
// Получить всех сотрудников
public List<Employee> getEmployees() {
return new ArrayList<>(employees); // Копия для инкапсуляции
}
// Найти сотрудника по ID
public Employee findEmployee(String id) {
return employees.stream()
.filter(e -> e.getId().equals(id))
.findFirst()
.orElse(null);
}
// Получить общую зарплату
public double getTotalSalaries() {
return employees.stream()
.mapToDouble(Employee::getSalary)
.sum();
}
}
Использование примера
public class Main {
public static void main(String[] args) {
// Создаём компанию
Company company = new Company("Tech Corp");
// Создаём сотрудников
Employee emp1 = new Employee("1", "Alice", "Developer", 80000);
Employee emp2 = new Employee("2", "Bob", "Manager", 90000);
Employee emp3 = new Employee("3", "Charlie", "Designer", 70000);
// Нанимаем сотрудников в компанию
company.hireEmployee(emp1);
company.hireEmployee(emp2);
company.hireEmployee(emp3);
// Выводим информацию
System.out.println("Всего сотрудников: " + company.getEmployees().size());
System.out.println("Общая зарплата: " + company.getTotalSalaries());
// Увольняем сотрудника
company.fireEmployee("2");
System.out.println("После увольнения: " + company.getEmployees().size());
// Важно: сотрудник Alice продолжает существовать даже после увольнения
System.out.println("Alice всё ещё существует: " + emp1.getName());
}
}
Ещё один пример: Университет и Студенты
public class Student {
private String studentId;
private String name;
private String major;
public Student(String studentId, String name, String major) {
this.studentId = studentId;
this.name = name;
this.major = major;
}
public String getStudentId() { return studentId; }
public String getName() { return name; }
public String getMajor() { return major; }
}
public class University {
private String name;
private List<Student> students; // Агрегация
public University(String name) {
this.name = name;
this.students = new ArrayList<>();
}
public void enrollStudent(Student student) {
students.add(student);
}
public void expelStudent(String studentId) {
students.removeIf(s -> s.getStudentId().equals(studentId));
}
public List<Student> getStudents() {
return new ArrayList<>(students);
}
public int getStudentCount() {
return students.size();
}
}
// Использование
University mit = new University("MIT");
Student student1 = new Student("S001", "John", "Computer Science");
mit.enrollStudent(student1);
mit.expelStudent("S001");
// Студент John существует независимо, может поступить в другой университет
University harvard = new University("Harvard");
harvard.enrollStudent(student1);
Агрегация с инициализацией через конструктор
public class Team {
private String teamName;
private List<Player> players; // Агрегация
// Конструктор с инициализацией агрегированных объектов
public Team(String teamName, List<Player> players) {
this.teamName = teamName;
// Копируем список для безопасности
this.players = new ArrayList<>(players);
}
public List<Player> getPlayers() {
return new ArrayList<>(players);
}
}
List<Player> squad = Arrays.asList(
new Player("Player 1", 10),
new Player("Player 2", 20)
);
Team team = new Team("FC United", squad);
Когда использовать агрегацию?
- Независимые объекты: когда часть может существовать без целого
- Слабая связь: когда не нужна тесная связь между классами
- Множество объектов: когда целое содержит коллекцию других объектов
- Модель "has-a": "Компания HAS-A сотрудники", "Университет HAS-A студенты"
Vs Композиция: когда использовать что?
// КОМПОЗИЦИЯ - строгая связь
public class House {
private Address address; // Адрес существует ТОЛЬКО в контексте дома
private List<Room> rooms; // Комнаты существуют ТОЛЬКО в доме
public House() {
this.address = new Address(); // Создаём новый адрес вместе с домом
this.rooms = new ArrayList<>();
}
}
// АГРЕГАЦИЯ - слабая связь
public class Garage {
private List<Car> cars; // Машины существуют независимо от гаража
public void parkCar(Car car) {
cars.add(car); // Машина была создана отдельно
}
}
Вывод
Агрегация - это способ составления объектов, где одна сущность "владеет" ссылками на другие, но не ответственна за их жизненный цикл. Это одна из основных техник проектирования для создания гибких и слабосвязанных архитектур.