implements
Aprenda como a palavra-chave "implements" do PHP aplica contratos de interface. Cobre sintaxe, múltiplas interfaces, constantes, type hinting e erros comuns.
A Palavra-chave implements do PHP
A palavra-chave implements informa ao PHP que uma classe concorda em cumprir o contrato definido por uma interface. Uma interface lista assinaturas de métodos (e opcionalmente constantes), mas nenhum corpo de método; uma classe que a implementa deve fornecer um corpo concreto para cada método que a interface declara. Caso contrário, o PHP lança um erro fatal antes que o programa seja executado.
Esta página aborda a sintaxe, a implementação de várias interfaces ao mesmo tempo, constantes de interface, type hinting em relação a interfaces, os erros comuns que você encontrará e como implements difere de extends. Se as interfaces ainda são novidade para você, comece com Interfaces PHP e O que é OOP.
Sintaxe
interface MyInterface {
public function doSomething(); // signature only — no body
}
class MyClass implements MyInterface {
public function doSomething() {
// the concrete implementation lives here
}
}MyClass implements MyInterface é uma promessa: "esta classe fornece uma versão funcional de cada método que MyInterface exige." A interface é o quê; a classe é o como.
Um exemplo básico
<?php
interface Animal {
public function makeSound();
}
class Dog implements Animal {
public function makeSound() {
echo "Woof!";
}
}
class Cat implements Animal {
public function makeSound() {
echo "Meow!";
}
}
$animals = [new Dog(), new Cat()];
foreach ($animals as $animal) {
$animal->makeSound(); // Output: Woof!Meow!
}Como Dog e Cat implementam Animal, qualquer código que espera um Animal pode trabalhar com qualquer um deles sem conhecer a classe concreta. Esta é a base do polimorfismo em PHP.
Implementando múltiplas interfaces
Ao contrário de extends (uma classe pode estender apenas um pai), uma classe pode implementar qualquer número de interfaces — separe-as com vírgulas. A classe deve satisfazer todos os métodos de cada interface que lista.
<?php
interface Logger {
public function log(string $message): void;
}
interface Notifier {
public function notify(string $message): void;
}
class AlertService implements Logger, Notifier {
public function log(string $message): void {
echo "LOG: $message\n";
}
public function notify(string $message): void {
echo "NOTIFY: $message\n";
}
}
$service = new AlertService();
$service->log("Disk space low"); // Output: LOG: Disk space low
$service->notify("Disk space low"); // Output: NOTIFY: Disk space lowÉ assim que o PHP obtém os benefícios da herança múltipla (compartilhar vários contratos) sem suas desvantagens (implementações herdadas ambíguas).
Constantes de interface e type hinting
Uma interface pode declarar constantes, e uma classe que a implementa as acessa como se fossem suas. O verdadeiro poder, porém, está no type hinting: quando você define o tipo de um parâmetro como a interface, qualquer classe que a implementa é aceita — assim você pode trocar implementações livremente.
<?php
interface PaymentGateway {
const CURRENCY = "USD";
public function charge(float $amount): bool;
}
class StripeGateway implements PaymentGateway {
public function charge(float $amount): bool {
echo "Charging " . self::CURRENCY . " $amount\n";
return true;
}
}
// Accepts ANY PaymentGateway, not just StripeGateway
function processPayment(PaymentGateway $gateway, float $amount): void {
$gateway->charge($amount);
}
processPayment(new StripeGateway(), 49.99); // Output: Charging USD 49.99Você também pode verificar um objeto em relação a uma interface em tempo de execução com instanceof:
var_dump($gateway instanceof PaymentGateway); // bool(true)Erros comuns e armadilhas
- Omitir um método é fatal. Se uma classe pular até mesmo um método de interface, o PHP lança
Fatal error: Class X contains 1 abstract method and must therefore be declared abstract or implement the remaining methods. A verificação ocorre em tempo de compilação, antes que qualquer código seja executado. - As assinaturas devem ser compatíveis. Sua implementação deve manter os tipos de parâmetro e retorno declarados pela interface (você pode ampliar os tipos de parâmetro e restringir os tipos de retorno de acordo com as regras de variância do PHP, mas incompatibilidades são fatais).
- Métodos de interface são implicitamente
public. Você não pode implementar um método de interface comoprotectedouprivate. - Interfaces podem estender interfaces. Use
interface B extends Apara construir sobre outra interface; uma classe que implementaBdeve satisfazer os métodos de ambas. Observe que isso usaextends, nãoimplements.
implements vs extends
Essas palavras-chave são fáceis de confundir:
extends | implements | |
|---|---|---|
| Usado com | uma classe pai (ou interface→interface) | uma ou mais interfaces |
| Herda código? | sim — propriedades e corpos de métodos | não — apenas o contrato (assinaturas) |
| Quantas? | uma classe estende uma classe | uma classe implementa muitas interfaces |
Uma classe pode fazer os dois ao mesmo tempo: class Circle extends Shape implements JsonSerializable { ... }. Para detalhes sobre herança, veja PHP extends e, quando quiser implementações parciais, classes abstratas PHP.
Quando usar implements
Use uma interface e implements quando:
- Várias classes não relacionadas precisam ser intercambiáveis (por exemplo, múltiplos gateways de pagamento, loggers ou drivers de cache).
- Você quer fazer type hint em uma capacidade em vez de uma classe concreta, mantendo o código fracamente acoplado e fácil de testar com mocks.
- Você está definindo um contrato de API público que outras classes — incluindo as escritas posteriormente ou por outras equipes — devem respeitar.
Se em vez disso você precisar compartilhar código de implementação real entre classes relacionadas, use herança de classe (extends) ou uma classe abstrata.