Composição
Em sistemas reais, objetos quase nunca vivem sozinhos. Um pedido contém itens, um funcionário tem um departamento, um usuário tem um perfil. Em vez de espalhar dados soltos, você agrupa em classes e as compõe. Dominar composição é essencial para modelar domínios complexos de forma organizada e reutilizável.
O PROBLEMA
Endereco(rua,cidade) e Pessoa com atributo Endereco.
EXEMPLO
p.endereco.cidade → Recife
SOBRE O CONCEITO
Composição é quando uma classe tem um atributo que é outro objeto. Na prática, você declara o campo do tipo da classe e depois o instancia com new. O erro mais comum é esquecer de instanciar o objeto interno, gerando NullPointerException ao acessar seus atributos, como em p.endereco.cidade. Isso acontece porque p.endereco é null até que você faça p.endereco = new Endereco() ou inicialize no construtor. Sempre verifique se cada objeto componente foi criado antes de usá-lo.
RESOLUÇÃO