Desafio PHP

Sistema de notificações com final e abstract

Enunciado

Crie uma classe abstrata Notificador com o método abstrato enviar(string $mensagem): void e um método final registrarLog(string $mensagem): void que imprime "[LOG] $mensagem". Implemente EmailNotificador e SmsNotificador que estendem Notificador. Cada um deve chamar registrarLog antes de enviar. Instancie ambos e envie uma mensagem.

Requisitos

  • Notificador deve ser abstract e ter enviar abstrato e registrarLog final.
  • As classes filhas devem implementar enviar e chamar registrarLog.
  • registrarLog deve ser final para não ser sobrescrito.
  • A saída deve mostrar o log seguido da mensagem de envio específica.

Código inicial

<?php
abstract class Notificador {
    abstract public function enviar(string $mensagem): void;
    final public function registrarLog(string $mensagem): void {
        // implemente
    }
}

class EmailNotificador extends Notificador {
    // implemente
}

class SmsNotificador extends Notificador {
    // implemente
}

$email = new EmailNotificador();
$email->enviar('Olá');
$sms = new SmsNotificador();
$sms->enviar('Olá');

Saída esperada

[LOG] Olá
Enviando e-mail: Olá
[LOG] Olá
Enviando SMS: Olá
Ver dica

Dentro de enviar, chame $this->registrarLog($mensagem) antes de imprimir a mensagem específica.

Mostrar solução
<?php
declare(strict_types=1);

abstract class Notificador
{
    abstract public function enviar(string $mensagem): void;

    final public function registrarLog(string $mensagem): void
    {
        echo "[LOG] {$mensagem}" . PHP_EOL;
    }
}

class EmailNotificador extends Notificador
{
    public function enviar(string $mensagem): void
    {
        $this->registrarLog($mensagem);
        echo "Enviando e-mail: {$mensagem}" . PHP_EOL;
    }
}

class SmsNotificador extends Notificador
{
    public function enviar(string $mensagem): void
    {
        $this->registrarLog($mensagem);
        echo "Enviando SMS: {$mensagem}" . PHP_EOL;
    }
}

$email = new EmailNotificador();
$email->enviar('Olá');
$sms = new SmsNotificador();
$sms->enviar('Olá');

Passo a passo

  1. Notificador é abstrata e define o contrato enviar.
  2. O método registrarLog é marcado como final, impedindo sobrescrita.
  3. EmailNotificador implementa enviar, chamando registrarLog e depois exibindo a mensagem específica.
  4. SmsNotificador faz o mesmo, mas com texto diferente.
  5. Instanciamos cada notificador e chamamos enviar('Olá').
  6. A saída mostra o log seguido da ação de envio.

Por que funciona

A classe abstrata garante que todo notificador tenha o método enviar, enquanto o método final assegura que o log seja sempre registrado da mesma forma, sem variações. As filhas especializam apenas o envio. Isso demonstra como abstract e final trabalham juntos para definir contratos e proteger comportamentos.

Erros comuns

  • Tentar sobrescrever registrarLog em uma classe filha: erro fatal Cannot override final method.
  • Esquecer de chamar registrarLog dentro de enviar: o log não aparece.
  • Declarar enviar sem o tipo de retorno void: o PHP pode emitir aviso de compatibilidade.

Outra forma de resolver

Poderia usar uma interface com um trait para o log, mas a classe abstrata com método final é mais direta para esse cenário.

Saída esperada

[LOG] Olá
Enviando e-mail: Olá
[LOG] Olá
Enviando SMS: Olá