PHP

Guia Completo de Interfaces e Classes Abstratas em PHP

6 min de leitura

Guia Completo de Interfaces e Classes Abstratas em PHP

Classes Abstratas em PHP Uma classe abstrata é um molde que não pode ser instanciada diretamente, servindo como base para outras classes. Ela define métodos que devem ser obrigatoriamente implementados pelas subclasses, garantindo contrato e estrutura consistente no seu código. Use-as quando você tem comportamento comum que precisa ser herdado, mas não faz sentido criar um objeto da classe pai sozinho. Classes abstratas podem ter métodos concretos (implementados) e abstratos (apenas assinatura). As subclasses herdam o comportamento concreto e obrigatoriamente implementam os abstratos. Isso torna seu código mais robusto e reutilizável. Interfaces em PHP O que são e quando usar Uma interface é um contrato que define apenas assinaturas de métodos, sem implementação. Diferente da herança (que é "é um"), interfaces definem "faz isso". Uma classe pode implementar múltiplas interfaces, mas pode herdar de apenas uma classe. Use interfaces quando quer garantir que classes diferentes façam o mesmo trabalho, independente de sua origem. Interfaces vs Classes Abstratas Interfaces definem o

<h2>Classes Abstratas em PHP</h2>

<p>Uma classe abstrata é um molde que não pode ser instanciada diretamente, servindo como base para outras classes. Ela define métodos que devem ser obrigatoriamente implementados pelas subclasses, garantindo contrato e estrutura consistente no seu código. Use-as quando você tem comportamento comum que precisa ser herdado, mas não faz sentido criar um objeto da classe pai sozinho.</p>

<pre><code class="language-php">abstract class Veiculo {

protected $marca;

abstract public function acelerar();

abstract public function frear();

public function __construct($marca) {

$this-&gt;marca = $marca;

}

public function getMarca() {

return $this-&gt;marca;

}

}

class Carro extends Veiculo {

public function acelerar() {

return &quot;Carro {$this-&gt;marca} acelerou!&quot;;

}

public function frear() {

return &quot;Carro {$this-&gt;marca} freou com segurança.&quot;;

}

}

$carro = new Carro(&quot;Toyota&quot;);

echo $carro-&gt;acelerar(); // Carro Toyota acelerou!

// $veiculo = new Veiculo(&quot;Ford&quot;); // Erro: não pode instanciar classe abstrata</code></pre>

<p>Classes abstratas podem ter métodos concretos (implementados) e abstratos (apenas assinatura). As subclasses herdam o comportamento concreto e obrigatoriamente implementam os abstratos. Isso torna seu código mais robusto e reutilizável.</p>

<h2>Interfaces em PHP</h2>

<h3>O que são e quando usar</h3>

<p>Uma interface é um contrato que define apenas assinaturas de métodos, sem implementação. Diferente da herança (que é &quot;é um&quot;), interfaces definem &quot;faz isso&quot;. Uma classe pode implementar múltiplas interfaces, mas pode herdar de apenas uma classe. Use interfaces quando quer garantir que classes diferentes façam o mesmo trabalho, independente de sua origem.</p>

<pre><code class="language-php">interface Pagavel {

public function procesarPagamento($valor);

public function obterStatusPagamento();

}

interface Rastreavel {

public function rastrear();

}

class Pedido implements Pagavel, Rastreavel {

private $id;

private $status = &quot;pendente&quot;;

public function __construct($id) {

$this-&gt;id = $id;

}

public function procesarPagamento($valor) {

$this-&gt;status = &quot;pago&quot;;

return &quot;Pagamento de R$ {$valor} processado.&quot;;

}

public function obterStatusPagamento() {

return $this-&gt;status;

}

public function rastrear() {

return &quot;Pedido {$this-&gt;id} em trânsito.&quot;;

}

}

$pedido = new Pedido(123);

echo $pedido-&gt;procesarPagamento(100); // Pagamento de R$ 100 processado.

echo $pedido-&gt;rastrear(); // Pedido 123 em trânsito.</code></pre>

<h3>Interfaces vs Classes Abstratas</h3>

<p>Interfaces definem o quê fazer, abstratas definem quê e como. Use abstratas para compartilhar código entre classes relacionadas; use interfaces para estabelecer contrato entre classes diferentes. Uma classe pode implementar várias interfaces, mas herdar de apenas uma abstrata.</p>

<pre><code class="language-php">abstract class Animal {

abstract public function fazer_som();

public function dormir() {

return &quot;Zzz... dormindo.&quot;;

}

}

interface Domesticavel {

public function treinar();

}

class Cachorro extends Animal implements Domesticavel {

public function fazer_som() {

return &quot;Au au!&quot;;

}

public function treinar() {

return &quot;Cachorro treinado com sucesso!&quot;;

}

}

$dog = new Cachorro();

echo $dog-&gt;fazer_som(); // Au au!

echo $dog-&gt;dormir(); // Zzz... dormindo.

echo $dog-&gt;treinar(); // Cachorro treinado com sucesso!</code></pre>

<h2>Padrões de Design Práticos</h2>

<h3>Dependency Injection com Interfaces</h3>

<p>Injetar dependências através de interfaces torna seu código flexível e testável. Em vez de instanciar objetos dentro da classe, você recebe como parâmetro uma implementação da interface.</p>

<pre><code class="language-php">interface RepositorioDB {

public function salvar($dados);

public function obter($id);

}

class Usuario {

private $db;

public function __construct(RepositorioDB $db) {

$this-&gt;db = $db;

}

public function criar($nome, $email) {

return $this-&gt;db-&gt;salvar([&#039;nome&#039; =&gt; $nome, &#039;email&#039; =&gt; $email]);

}

}

class MySQLRepository implements RepositorioDB {

public function salvar($dados) {

return &quot;Salvo no MySQL: &quot; . json_encode($dados);

}

public function obter($id) {

return &quot;Obtido do MySQL com ID: $id&quot;;

}

}

class MockRepository implements RepositorioDB {

public function salvar($dados) {

return &quot;Simulado: &quot; . json_encode($dados);

}

public function obter($id) {

return &quot;Mock data para ID: $id&quot;;

}

}

// Fácil trocar implementação sem mudar Usuario

$repo = new MySQLRepository();

$usuario = new Usuario($repo);

echo $usuario-&gt;criar(&quot;João&quot;, &quot;joao@email.com&quot;);</code></pre>

<h2>Conclusão</h2>

<p><strong>Três aprendizados principais:</strong> (1) Classes abstratas são bases para famílias de classes relacionadas, garantindo que subclasses implementem métodos específicos; (2) Interfaces estabelecem contratos entre classes não relacionadas, permitindo múltiplas implementações do mesmo comportamento; (3) Usar ambas corretamente, combinadas com dependency injection, resulta em código robusto, testável e fácil de manter. Domine esses conceitos e você elevará significativamente a qualidade de suas aplicações PHP.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://www.php.net/manual/en/language.oop5.abstract.php" target="_blank" rel="noopener noreferrer">PHP Manual - Abstract Classes</a></li>

<li><a href="https://www.php.net/manual/en/language.oop5.interfaces.php" target="_blank" rel="noopener noreferrer">PHP Manual - Interfaces</a></li>

<li><a href="https://refactoring.guru/design-patterns/php" target="_blank" rel="noopener noreferrer">Design Patterns PHP - Refactoring Guru</a></li>

<li><a href="https://www.oreilly.com/library/view/clean-code/9780134494166/" target="_blank" rel="noopener noreferrer">Clean Code em PHP - Matthias Noback</a></li>

<li><a href="https://www.php-fig.org/psr/psr-12/" target="_blank" rel="noopener noreferrer">PSR-12: Extended Coding Style Guide</a></li>

</ul>

Comentários

Mais em PHP

Dominando PHP_CodeSniffer e PHPStan: Qualidade Estática de Código em Projetos Reais
Dominando PHP_CodeSniffer e PHPStan: Qualidade Estática de Código em Projetos Reais

PHPCodeSniffer: Implementando Padrões de Código PHPCodeSniffer (PHPCS) é uma...

Boas Práticas de Namespaces e Autoloading com PSR-4 para Times Ágeis
Boas Práticas de Namespaces e Autoloading com PSR-4 para Times Ágeis

O que são Namespaces? Namespaces são mecanismos de organização de código que...

Laravel Testes com PHPUnit e Pest: Do Básico ao Avançado
Laravel Testes com PHPUnit e Pest: Do Básico ao Avançado

PHPUnit: Fundamentos e Configuração PHPUnit é o framework de testes mais cons...