Menu
Coddy logo textTech

Composição vs. Herança

Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy. Lição 56 de 91.

No capítulo anterior, você aprendeu que os traits fornecem uma capacidade de "tem-um", enquanto a herança estabelece uma relação de "é-um". A composição leva o conceito de "tem-um" além, construindo objetos complexos a partir de objetos mais simples e armazenando-os como propriedades, em vez de herdar deles.

Com herança, um Car pode estender Vehicle. Com composição, um Car contém um objeto Engine:

<?php
class Engine {
    public function start(): string {
        return "Engine started";
    }
}

class Car {
    private Engine $engine;
    
    public function __construct() {
        $this->engine = new Engine();
    }
    
    public function start(): string {
        return $this->engine->start();
    }
}

$car = new Car();
echo $car->start();

Saída:

Engine started

A classe Car não herda de Engine — ela possui uma. Essa abordagem oferece vantagens significativas: você pode trocar o mecanismo por uma implementação diferente, as classes permanecem fracamente acopladas e você evita as hierarquias rígidas que a herança profunda cria.

Uma diretriz comum em POO é "prefira composição à herança." A herança funciona bem para hierarquias de tipos genuínas (um Dog realmente é um Animal), mas a composição se destaca quando você está reunindo funcionalidades de partes independentes. Você pode combinar vários objetos, substituí-los em tempo de execução e testar componentes isoladamente.

A próxima lição explora a injeção de dependência, que se baseia diretamente na composição ao controlar como os objetos recebem suas dependências.

challenge icon

Desafio

Fácil

Vamos construir um sistema de computador usando composição, em que um Computer é montado a partir de objetos de componentes separados, em vez de herdar deles. Isso demonstra como a composição permite construir objetos complexos a partir de partes mais simples e independentes.

Você organizará seu código em três arquivos:

  • Processor.php: crie uma classe Processor que represente uma CPU. Use a promoção de construtor para definir um $model (string) privado e um $cores (inteiro) privado. Adicione um método getSpecs() que retorne "[model] ([cores] cores)".
  • Memory.php: crie uma classe Memory que represente a RAM. Use a promoção de construtor para definir um $size (inteiro que representa GB) privado. Adicione um método getCapacity() que retorne "[size]GB RAM".
  • main.php: inclua os dois arquivos de componentes e crie uma classe Computer que use composição. O Computer deve:
    • Armazenar um objeto Processor e um objeto Memory como propriedades privadas
    • Aceitar um modelo de processador, uma quantidade de núcleos e um tamanho de memória em seu construtor
    • Criar os objetos de componentes internamente durante a construção
    • Ter um método describe() que retorne "Computer with [processor specs] and [memory capacity]"

    Você receberá três entradas: um modelo de processador, uma quantidade de núcleos e um tamanho de memória em GB. Crie um Computer com essas especificações e imprima o resultado da chamada de describe().

Observe como o Computer não estende Processor nem Memory. Ele os contém. Essa relação de composição do tipo "tem um" mantém cada componente independente e reutilizável, ao mesmo tempo que permite que o Computer delegue tarefas às suas partes quando necessário.

Experimente você mesmo

<?php
require_once 'Processor.php';
require_once 'Memory.php';

class Computer
{
    // TODO: Defina propriedades privadas para armazenar objetos Processor e Memory

    // TODO: O construtor deve aceitar o modelo do processador, a quantidade de núcleos e o tamanho da memória
    // e criar os objetos dos componentes internamente
    public function __construct()
    {
        // TODO: Crie os objetos Processor e Memory e armazene-os
    }

    // TODO: Implemente o método describe() que retorna
    // "Computer with [processor specs] and [memory capacity]"
    public function describe(): string
    {
        // TODO: Delegue aos objetos dos componentes e retorne a string formatada
    }
}

// Ler a entrada
$processorModel = trim(fgets(STDIN));
$cores = intval(fgets(STDIN));
$memorySize = intval(fgets(STDIN));

// TODO: Crie um Computer com as especificações fornecidas e imprima o resultado de describe()

?>
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 PHP online