Desafio PHP

Polimorfismo com interfaces e cálculo de áreas

Enunciado

Crie a interface Forma com os métodos area(): float e nome(): string. Crie as classes Circulo (raio) e Quadrado (lado) que a implementam. Crie uma função relatorio(array $formas): void que exibe o nome e a área de cada forma, formatada com duas casas decimais. No final, exiba a soma total das áreas.

Requisitos

  • A interface Forma deve ter os métodos area e nome.
  • As classes Circulo e Quadrado devem implementar Forma.
  • A função relatorio deve receber um array de Forma e imprimir nome e área com duas casas decimais.
  • O programa deve exibir a soma total das áreas.

Código inicial

<?php

// Defina a interface Forma

// Defina as classes Circulo e Quadrado

// Defina a função relatorio

// Teste

Saída esperada

Círculo: 12.57
Quadrado: 9.00
Total: 21.57
Ver dica

Use number_format($forma->area(), 2) para formatar. Para a soma, percorra o array novamente ou acumule durante o relatório.

Mostrar solução
<?php

interface Forma
{
    public function area(): float;
    public function nome(): string;
}

class Circulo implements Forma
{
    public function __construct(private float $raio) {}

    public function area(): float
    {
        return M_PI * $this->raio ** 2;
    }

    public function nome(): string
    {
        return 'Círculo';
    }
}

class Quadrado implements Forma
{
    public function __construct(private float $lado) {}

    public function area(): float
    {
        return $this->lado ** 2;
    }

    public function nome(): string
    {
        return 'Quadrado';
    }
}

function relatorio(array $formas): void
{
    $total = 0.0;
    foreach ($formas as $forma) {
        $area = $forma->area();
        $total += $area;
        echo $forma->nome() . ': ' . number_format($area, 2) . PHP_EOL;
    }
    echo 'Total: ' . number_format($total, 2) . PHP_EOL;
}

$formas = [
    new Circulo(2),
    new Quadrado(3),
];

relatorio($formas);

Passo a passo

  1. A interface Forma declara os métodos area e nome, sem implementação.
  2. Circulo implementa Forma: o construtor promove $raio; area usa M_PI (constante nativa do PHP) e ** 2 para o quadrado; nome retorna 'Círculo'.
  3. Quadrado também implementa Forma: area retorna $this->lado ** 2.
  4. A função relatorio aceita um array de Forma (polimorfismo). Inicializa $total = 0.0 e percorre cada forma.
  5. Para cada forma, chama area() e nome(), acumula em $total e imprime com number_format($area, 2).
  6. Após o loop, imprime o total formatado.
  7. No código principal, criamos um array com instâncias de Circulo e Quadrado e chamamos relatorio.

Por que funciona

A função relatorio não conhece as classes concretas, apenas a interface Forma. Isso é polimorfismo: qualquer objeto que implemente Forma pode ser passado. O array $formas contém tipos diferentes, mas todos respondem aos mesmos métodos. A soma é feita de forma genérica.

Erros comuns

  • Não implementar todos os métodos: se Quadrado esquecer nome(), o PHP lança erro fatal.
  • Passar objeto que não implementa a interface: relatorio([new stdClass()]) gera TypeError.
  • Esquecer de formatar: sem number_format, a saída teria muitas casas decimais, como 12.566370614359. Use number_format para duas casas.
  • Usar pi() em vez de M_PI: ambos funcionam, mas M_PI é constante e mais idiomático.

Outra forma de resolver

Usar array_reduce para calcular o total e array_map para exibir, mas o loop foreach é mais claro para iniciantes.

Saída esperada

Círculo: 12.57
Quadrado: 9.00
Total: 21.57