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.
Desafio
FácilVamos 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) edepartment(String). Inclua um construtor para inicializar ambos os campos e métodos getter para cada um. SobrescrevatoString()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) edurationMinutes(int). Inclua um construtor e getters. SobrescrevatoString()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) electures(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 de45minutos. 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 delistLectures().
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()
}
}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
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave thisMétodosCampos (Atributos)Método ConstrutorSobrecarga de ConstrutorRecapitulação - Calculadora Simples4Herança
Herança Básica (extends)A Palavra-chave superSobrescrita de Método (@Override)Encadeamento de ConstrutoresA Classe ObjectHerança Simples e MultinívelPor que não há Herança Múltipla de ClassesRecapitulação - Hierarquia de Funcionários7Métodos Especiais e a Classe Object
Método toString()equals() e hashCode()Método clone()compareTo() e ComparableInterface ComparatorRecapitulação - Ordenação Personalizada2Modificadores de Acesso e Encapsulamento
Visão Geral dos Níveis de AcessoMétodos Getter e SetterOcultação de InformaçõesA Palavra-chave finalRecapitulação - Gerenciador de Conta Bancária5Polimorfismo
Fundamentos de Sobrecarga de MétodosSobrescrita de Métodos (Tempo de Execução)Upcasting e DowncastingO Operador instanceofClasses e Métodos AbstratosRecapitulação - Calculadora de Formas8Conceitos Avançados de OOP
Composição vs HerançaAgregação vs ComposiçãoClasses Internas, Aninhadas e AnônimasEnums e Métodos de EnumRecords (Java 16+)Classes Seladas (Java 17+)11Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão BuilderPadrão ObserverPadrão Strategy3Propriedades de Classe e Membros Estáticos
Variáveis de Instância vs EstáticasMétodos EstáticosBlocos EstáticosConstantes (static final)Recapitulação - Contador e Utilitário6Interfaces e Classes Abstratas
Introdução às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesDefault e Static em InterfacesClasses Abstratas vs InterfacesInterfaces FuncionaisRecapitulação - Sistema de Pagamento9Generics
Introdução a GenericsClasses GenéricasMétodos GenéricosParâmetros de Tipos DelimitadosWildcards (?, extends, super)Recapitulação - Container Genérico12Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão IteratorPratique por conta própria: Compilador de Java online