<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->marca = $marca;
}
public function getMarca() {
return $this->marca;
}
}
class Carro extends Veiculo {
public function acelerar() {
return "Carro {$this->marca} acelerou!";
}
public function frear() {
return "Carro {$this->marca} freou com segurança.";
}
}
$carro = new Carro("Toyota");
echo $carro->acelerar(); // Carro Toyota acelerou!
// $veiculo = new Veiculo("Ford"); // 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 é "é 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.</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 = "pendente";
public function __construct($id) {
$this->id = $id;
}
public function procesarPagamento($valor) {
$this->status = "pago";
return "Pagamento de R$ {$valor} processado.";
}
public function obterStatusPagamento() {
return $this->status;
}
public function rastrear() {
return "Pedido {$this->id} em trânsito.";
}
}
$pedido = new Pedido(123);
echo $pedido->procesarPagamento(100); // Pagamento de R$ 100 processado.
echo $pedido->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 "Zzz... dormindo.";
}
}
interface Domesticavel {
public function treinar();
}
class Cachorro extends Animal implements Domesticavel {
public function fazer_som() {
return "Au au!";
}
public function treinar() {
return "Cachorro treinado com sucesso!";
}
}
$dog = new Cachorro();
echo $dog->fazer_som(); // Au au!
echo $dog->dormir(); // Zzz... dormindo.
echo $dog->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->db = $db;
}
public function criar($nome, $email) {
return $this->db->salvar(['nome' => $nome, 'email' => $email]);
}
}
class MySQLRepository implements RepositorioDB {
public function salvar($dados) {
return "Salvo no MySQL: " . json_encode($dados);
}
public function obter($id) {
return "Obtido do MySQL com ID: $id";
}
}
class MockRepository implements RepositorioDB {
public function salvar($dados) {
return "Simulado: " . json_encode($dados);
}
public function obter($id) {
return "Mock data para ID: $id";
}
}
// Fácil trocar implementação sem mudar Usuario
$repo = new MySQLRepository();
$usuario = new Usuario($repo);
echo $usuario->criar("João", "joao@email.com");</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>