Menu
Coddy logo textTech

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 relacionamentos "tem-um", mas diferem em um aspecto crucial: propriedade e dependência do 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 em 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 possui rooms
        }
    }
}

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 distinção fundamental: na composição, o contêiner cria suas partes internamente. Na agregação, os objetos são passados de fora. Quando uma Team é excluída, os objetos Player ainda existem. Quando uma House é excluída, seus objetos Room também desaparecem.

challenge icon

Desafio

Fácil

Vamos criar um sistema de cursos universitários que demonstre tanto agregação quanto 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 deles. Substitua 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. Substitua toString() para retornar: Lecture: [topic] ([durationMinutes] min)
  • Course.java: é aqui que você demonstrará ambas as 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 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: reúna 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 e passado para o Course (agregação: o professor poderia ministrar outros cursos ou existir sem este curso). As Lectures são criadas dentro do construtor de 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);
        
        // Ler entradas
        String professorName = scanner.nextLine();
        String department = scanner.nextLine();
        String courseTitle = scanner.nextLine();
        int numberOfLectures = scanner.nextInt();
        
        // TODO: Criar um objeto Professor (existe independentemente - agregação)
        
        // TODO: Criar um objeto Course, passando o professor (agregação)
        // O course criará suas próprias lectures internamente (composição)
        
        // TODO: Imprimir o resultado de getInfo()
        
        // TODO: Imprimir uma linha vazia
        
        // TODO: Imprimir 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