Menu
CoddyTech

Agregação vs Composição

Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy. Lição 48 de 87.

Tanto a agregação quanto a composição são formas de relações do tipo "tem um", mas diferem em um aspecto crucial: dependência de propriedade e ciclo de vida.

Na composição, o objeto contido não pode existir independentemente do contêiner. Quando o contêiner é destruído, suas partes também são. Pense em uma House e seus objetos Room: os cômodos não existem sem a casa:

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 cria e é proprietária dos cômodos
        }
    }
}

Na agregação, o objeto contido pode existir de forma independente. O contêiner usa o objeto, mas não controla seu ciclo de vida. Considere um Team e seus objetos Player: os jogadores existem mesmo sem um time:

class Team {
    private List<Player> players;
    
    public Team() {
        players = new ArrayList<>();
    }
    
    public void addPlayer(Player player) {
        players.add(player);  // Team usa jogadores existentes
    }
}

A principal diferença: na composição, o contêiner cria suas partes internamente. Na agregação, os objetos são passados de fora. Quando um Team é excluído, os objetos Player ainda existem. Quando um House é excluído, seus objetos Room também desaparecem.

challenge icon

Desafio

Fácil

Vamos criar um sistema de cursos universitários que demonstra agregação e composição. Você verá como um Course possui seus objetos Lecture (composição), enquanto apenas referencia objetos Professor que existem independentemente (agregação).

Você organizará seu código em quatro arquivos:

  • Professor.java: Crie uma classe que represente um professor que pode existir independentemente de qualquer curso. Um Professor tem dois campos privados: name (String) e department (String). Inclua um construtor para inicializar ambos os campos e métodos getter para cada um. Sobrescreva toString() para retornar: Prof. [name] ([department])
  • Lecture.java: Crie uma classe que represente uma aula que só faz sentido dentro de um curso. Uma Lecture tem dois campos privados: topic (String) e durationMinutes (int). Inclua um construtor e getters. Sobrescreva toString() para retornar: Lecture: [topic] ([durationMinutes] min)
  • Course.java: É aqui que você demonstrará as duas relações! Um Course tem três campos privados: title (String), professor (Professor - agregação) e lectures (um array de objetos Lecture - composição).

    O construtor recebe o título do curso, um objeto Professor (passado de fora - agregação) e o número de aulas. Dentro do construtor, crie o array de Lecture e preencha-o com novos objetos Lecture. Para cada aula no índice i, crie-a com o tópico "Topic " + (i + 1) e a duração de 45 minutos. Essa criação interna demonstra a composição.

    Adicione um método getInfo() que retorne uma String com várias linhas:

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

    Adicione também um método listLectures() que retorne uma String com o toString() de cada aula em sua própria linha.

  • Main.java: Junte tudo! Você receberá quatro entradas: nome do professor (String), departamento do professor (String), título do curso (String) e número de aulas (int).

    Primeiro, crie um Professor com o nome e o departamento fornecidos. Esse professor existe independentemente. Em seguida, crie um Course, passando o título, o professor (agregação) e a quantidade de aulas (o curso criará suas próprias aulas internamente - composição).

    Imprima o resultado de getInfo(), depois imprima uma linha vazia e, em seguida, imprima o resultado de listLectures().

Você receberá quatro entradas nesta ordem: nome do professor, departamento, título do curso e número de aulas.

Observe a principal diferença: o Professor é criado fora do Course e passado para ele (agregação: o professor poderia dar aulas em outros cursos ou existir sem este curso). As Lectures são criadas dentro do construtor do Course (composição). Elas pertencem exclusivamente a este curso e não existiriam sem ele.

Experimente você mesmo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Leia as entradas
        String professorName = scanner.nextLine();
        String department = scanner.nextLine();
        String courseTitle = scanner.nextLine();
        int numberOfLectures = scanner.nextInt();
        
        // TODO: Crie um objeto Professor (existe independentemente — agregação)
        
        // TODO: Crie um objeto Course, passando o professor (agregação)
        // O curso criará suas próprias aulas internamente (composição)
        
        // TODO: Imprima o resultado de getInfo()
        
        // TODO: Imprima uma linha em branco
        
        // TODO: Imprima o resultado de listLectures()
        
    }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de Java online