Menu
Coddy logo textTech

Agregacja a kompozycja

Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 48 z 87.

Zarówno agregacja, jak i kompozycja są formami relacji „ma”, ale różnią się pod jednym kluczowym względem: własnością i zależnością cyklu życia.

W kompozycji zawarty obiekt nie może istnieć niezależnie od kontenera. Gdy kontener zostaje zniszczony, jego części również. Pomyśl o obiektach House i Room: pokoje nie istnieją bez domu:

class House {
    private Room[] rooms;
    
    public House(int numRooms) {
        rooms = new Room[numRooms];
        for (int i = 0; i < numRooms; i++) {
            rooms[i] = new Room();  // House tworzy pokoje i jest ich właścicielem
        }
    }
}

W przypadku agregacji zawarty obiekt może istnieć niezależnie. Kontener używa obiektu, ale nie kontroluje jego cyklu życia. Rozważmy Team i jego obiekty Player: gracze istnieją nawet bez drużyny:

class Team {
    private List<Player> players;
    
    public Team() {
        players = new ArrayList<>();
    }
    
    public void addPlayer(Player player) {
        players.add(player);  // Team korzysta z istniejących graczy
    }
}

Kluczowa różnica: w kompozycji kontener tworzy swoje części wewnętrznie. W agregacji obiekty są przekazywane z zewnątrz. Gdy Team zostaje usunięty, obiekty Player nadal istnieją. Gdy House zostaje usunięty, jego obiekty Room również znikają.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system kursów uniwersyteckich, który demonstruje zarówno agregację, jak i kompozycję. Zobaczysz, jak Course posiada obiekty Lecture (kompozycja), a jednocześnie jedynie odwołuje się do obiektów Professor, które istnieją niezależnie (agregacja).

Rozmieścisz swój kod w czterech plikach:

  • Professor.java: Utwórz klasę reprezentującą profesora, który może istnieć niezależnie od dowolnego kursu. Profesor ma dwa prywatne pola: name (String) i department (String). Dodaj konstruktor inicjalizujący oba pola oraz metody pobierające wartość każdego z nich. Nadpisz toString(), aby zwracała: Prof. [name] ([department])
  • Lecture.java: Utwórz klasę reprezentującą wykład, który ma sens tylko w ramach kursu. Wykład ma dwa prywatne pola: topic (String) i durationMinutes (int). Dodaj konstruktor i metody pobierające wartości pól. Nadpisz toString(), aby zwracała: Lecture: [topic] ([durationMinutes] min)
  • Course.java: To tutaj zademonstrujesz obie relacje! Kurs ma trzy prywatne pola: title (String), professor (Professor — agregacja) oraz lectures (tablica obiektów Lecture — kompozycja).

    Konstruktor przyjmuje tytuł kursu, obiekt Professor (przekazany z zewnątrz — agregacja) oraz liczbę wykładów. Wewnątrz konstruktora utwórz tablicę Lecture i wypełnij ją nowymi obiektami Lecture. Dla każdego wykładu o indeksie i utwórz go z tematem "Topic " + (i + 1) i czasem trwania 45 minut. To tworzenie wewnątrz klasy demonstruje kompozycję.

    Dodaj metodę getInfo(), która zwraca wielowierszowy String:

    Course: [title]
    Instructor: [professor.toString()]
    Lectures: [number of lectures]

    Dodaj także metodę listLectures(), która zwraca String zawierający wynik toString() każdego wykładu w osobnym wierszu.

  • Main.java: Połącz wszystkie elementy! Otrzymasz cztery dane wejściowe: imię i nazwisko profesora (String), wydział profesora (String), tytuł kursu (String) oraz liczbę wykładów (int).

    Najpierw utwórz obiekt Professor z podanym imieniem i nazwiskiem oraz wydziałem. Ten profesor istnieje niezależnie. Następnie utwórz obiekt Course, przekazując mu tytuł, profesora (agregacja) i liczbę wykładów (kurs utworzy własne wykłady wewnętrznie — kompozycja).

    Wypisz wynik getInfo(), następnie pusty wiersz, a potem wynik listLectures().

Otrzymasz kolejno cztery dane wejściowe: imię i nazwisko profesora, wydział, tytuł kursu oraz liczbę wykładów.

Zwróć uwagę na kluczową różnicę: obiekt Professor jest tworzony na zewnątrz i przekazywany do obiektu Course (agregacja: profesor mógłby prowadzić inne kursy lub istnieć bez tego kursu). Obiekty Lecture są tworzone wewnątrz konstruktora Course (kompozycja). Należą wyłącznie do tego kursu i nie istniałyby bez niego.

Spróbuj swoich sił

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Odczytaj dane wejściowe
        String professorName = scanner.nextLine();
        String department = scanner.nextLine();
        String courseTitle = scanner.nextLine();
        int numberOfLectures = scanner.nextInt();
        
        // TODO: Utwórz obiekt Professor (istnieje niezależnie — agregacja)
        
        // TODO: Utwórz obiekt Course, przekazując mu obiekt Professor (agregacja)
        // Kurs utworzy własne wykłady wewnętrznie (kompozycja)
        
        // TODO: Wypisz wynik getInfo()
        
        // TODO: Wypisz pustą linię
        
        // TODO: Wypisz wynik listLectures()
        
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Java online