Introdução
Em programação orientada a objetos (POO), interfaces são contratos que definem um conjunto de métodos que uma classe deve implementar, sem revelar detalhes de implementação. Ao usar interfaces, garantimos que diferentes classes sigam a mesma “assinatura” de métodos, aumentando a flexibilidade, a legibilidade e a manutenibilidade do código.
Neste artigo, vamos explorar como criar e usar interfaces em PHP, Java e JavaScript (via TypeScript-like patterns), com exemplos claros para cada linguagem.
O que são Interfaces?
Contrato de métodos: uma interface declara métodos (assinaturas) sem corpo.
Herança múltipla “segura”: ao contrário de herdar classes concretas (que pode gerar conflitos), uma classe pode implementar várias interfaces.
Polimorfismo: objetos de classes diferentes podem ser tratados de forma uniforme se implementam a mesma interface.
1. Interfaces em PHP
A partir do PHP 5, interfaces fazem parte do núcleo da linguagem.
<?php
// Define a interface que declara dois métodos
interface LoggerInterface {
public function logInfo(string $message): void;
public function logError(string $message): void;
}
// Classe que implementa LoggerInterface usando log em arquivo
class FileLogger implements LoggerInterface {
private string $filePath;
public function __construct(string $filePath) {
$this->filePath = $filePath;
}
public function logInfo(string $message): void {
$t
his->writeLog('INFO', $message);
}
public function logError(string $message): void {
$this->writeLog('ERROR', $message);
}
private function writeLog(string $level, string $message): void {
$timestamp = date('Y-m-d H:i:s');
file_put_contents(
$this->filePath,
"[$timestamp] [$level] $message" . PHP_EOL,
FILE_APPEND
);
}
}
$logger = new FileLogger(__DIR__ . '/app.log');
$logger->logInfo('Aplicação iniciada');
$logger->logError('Erro ao conectar ao banco de dados');
Explicação:
interface LoggerInterface
declara dois métodos sem implementação.class FileLogger implements LoggerInterface
obriga o PHP a exigir os métodoslogInfo
elogError
.O método privado
writeLog
centraliza a lógica de escrita em arquivo.
2. Interfaces em Java
Em Java, interfaces são parte essencial da linguagem e suportam, desde o Java 8, métodos default
e static
.
// Declaração da interface
public interface Shape { double area();// retorna área
double perimeter();// retorna perímetro
// Método default (implementação opcional)
default void describe() {
System.out.println(“Sou uma forma geométrica.”);
}
}
// Classe que implementa Shape para círculos
public class Circle implements Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
@Override
public double perimeter() {
return 2 * Math.PI * radius;
}
}
// Exemplo de uso
public class Main {
public static void main(String[] args) {
Shape c = new Circle(5.0);
System.out.printf(“Área: %.2f%n”, c.area());
System.out.printf(“Perímetro: %.2f%n”, c.perimeter());
c.describe(); // método default
}
}
Explicação:
interface Shape
define dois métodos abstratos e um métododefault
com implementação.class Circle implements Shape
deve implementararea()
eperimeter()
.Métodos
default
permitem comportamento padrão compartilhado sem forçar todas as implementações a reescrevê-lo.
3. “Interfaces” em JavaScript
JavaScript não possui interfaces nativas, mas podemos simular contratos via duck typing ou utilizar TypeScript para tipagem estática. Aqui veremos um padrão simples em JS puro:
// “Interface” Shape: definimos um objeto que deve ter métodos area e perimeter
function ensureShape(obj) {
if (typeof obj.area !== 'function' || typeof obj.perimeter !== 'function') {
throw new Error('Objeto não implementa a interface Shape');
}
}
// Implementação para círculos
class Circle {
constructor(radius) {
this.radius = radius;
}
area() {
return Math.PI * this.radius ** 2;
}
perimeter() {
return 2 * Math.PI * this.radius;
}
}
// Uso
const c = new Circle(5);
ensureShape(c);
console.log('Área:', c.area().toFixed(2));
console.log('Perímetro:', c.perimeter().toFixed(2));
Explicação:
A função
ensureShape
verifica a presença dos métodos exigidos.class Circle
implementaarea
eperimeter
, satisfazendo o “contrato”.Essa abordagem é dinâmica — erros são detectados em tempo de execução.
Bônus com TypeScript
interface Shape { area(): number; perimeter(): number; } class Circle implements Shape { constructor(private radius: number) {} area() { return Math.PI * this.radius ** 2; } perimeter() { return 2 * Math.PI * this.radius; } }
Vantagens do Uso de Interfaces
Desacoplamento: Código cliente não depende de implementações concretas.
Teste: Facilita mocking e stubbing em testes unitários.
Flexibilidade: Permite trocar implementações sem alterar quem as consome.
Documentação implícita: A interface descreve exatamente o que uma implementação deve oferecer.
Conclusão
Interfaces são peças-chave para escrever código coeso, flexível e de fácil manutenção em paradigmas orientados a objetos. Em PHP e Java temos suporte nativo; em JavaScript podemos simular ou usar TypeScript para tipagem estática. Adotar interfaces ajuda a:
Padronizar componentes de forma clara.
Garantir que múltiplas classes forneçam métodos consistentes.
Facilitar testes e evolução do sistema.
Experimente criar suas próprias interfaces nos próximos projetos e veja como seu código ganha em legibilidade e robustez!