W3docs

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.99

Você 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 como protected ou private.
  • Interfaces podem estender interfaces. Use interface B extends A para construir sobre outra interface; uma classe que implementa B deve satisfazer os métodos de ambas. Observe que isso usa extends, não implements.

implements vs extends

Essas palavras-chave são fáceis de confundir:

extendsimplements
Usado comuma classe pai (ou interface→interface)uma ou mais interfaces
Herda código?sim — propriedades e corpos de métodosnão — apenas o contrato (assinaturas)
Quantas?uma classe estende uma classeuma 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.

Prática

Prática
Qual é a função da palavra-chave 'implements' em PHP?
Qual é a função da palavra-chave 'implements' em PHP?
Was this page helpful?