Implementación de Interfaces
Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy — lección 28 de 91.
Ahora que entiendes qué son las interfaces, veamos cómo implementarlas realmente. Una clase implementa una interfaz utilizando la palabra clave implements, y debe proporcionar implementaciones concretas para todos los métodos declarados en esa interfaz.
<?php
interface Printable {
public function print();
}
class Document implements Printable {
private $content;
public function __construct($content) {
$this->content = $content;
}
public function print() {
return "Printing: " . $this->content;
}
}
$doc = new Document("Hello World");
echo $doc->print();
Salida:
Printing: Hello WorldLa clase Document implementa Printable proporcionando su propia versión del método print(). Si olvidas implementar un método requerido, PHP lanzará un error fatal.
Diferentes clases pueden implementar la misma interfaz a su propia manera:
<?php
class Invoice implements Printable {
private $amount;
public function __construct($amount) {
$this->amount = $amount;
}
public function print() {
return "Invoice Total: $" . $this->amount;
}
}
$invoice = new Invoice(150);
echo $invoice->print();
Salida:
Invoice Total: $150Tanto Document como Invoice cumplen con el contrato Printable, pero cada uno maneja la impresión de manera diferente según su propósito.
Punto clave: Usa implements para conectar una clase a una interfaz, luego define todos los métodos requeridos. Cada clase que implementa proporciona su propia lógica mientras garantiza que existan las mismas firmas de método.
Desafío
FácilVamos a construir un sistema de mensajería que demuestre cómo diferentes clases pueden implementar la misma interfaz de sus propias maneras únicas.
Crearás tres archivos que trabajan juntos para manejar diferentes tipos de mensajes:
Messageable.php— Define la interfazMessageablecon dos firmas de método:compose($content)ydeliver(). Esta interfaz establece el contrato que todos los tipos de mensajes deben seguir.Email.php— Crea una claseEmailque implementeMessageable. Incluye el archivo de la interfaz en la parte superior. La clase debe tener una propiedad privada$recipienty una propiedad privada$body. El constructor acepta la dirección del destinatario. Implementacompose($content)para almacenar el contenido en$bodyy devolver"Email composed". Implementadeliver()para devolver"Email to [recipient]: [body]".SMS.php— Crea una claseSMSque también implementeMessageable. Incluye el archivo de la interfaz en la parte superior. La clase debe tener una propiedad privada$phoneNumbery una propiedad privada$text. El constructor acepta el número de teléfono. Implementacompose($content)para almacenar el contenido en$texty devolver"SMS composed". Implementadeliver()para devolver"SMS to [phoneNumber]: [text]".
En main.php, incluye tanto el archivo de Email como el de SMS. Recibirás tres entradas: una dirección de correo electrónico, un número de teléfono y el contenido de un mensaje. Crea un objeto Email con la dirección de correo electrónico y un objeto SMS con el número de teléfono. Llama a compose() con el contenido del mensaje en ambos objetos, imprimiendo cada resultado en su propia línea. Luego llama a deliver() en ambos objetos, imprimiendo cada resultado en su propia línea. El orden debe ser: email compose, SMS compose, email deliver, SMS deliver.
Ambas clases cumplen con el mismo contrato Messageable, pero cada una maneja la composición y entrega de mensajes de acuerdo con su propio propósito: los correos electrónicos muestran la dirección del destinatario mientras que los mensajes SMS muestran el número de teléfono.
Hoja de referencia
Una clase implementa una interfaz utilizando la palabra clave implements y debe proporcionar implementaciones concretas para todos los métodos declarados en esa interfaz:
<?php
interface Printable {
public function print();
}
class Document implements Printable {
private $content;
public function __construct($content) {
$this->content = $content;
}
public function print() {
return "Printing: " . $this->content;
}
}
Múltiples clases pueden implementar la misma interfaz, cada una proporcionando su propia implementación:
<?php
class Invoice implements Printable {
private $amount;
public function __construct($amount) {
$this->amount = $amount;
}
public function print() {
return "Invoice Total: $" . $this->amount;
}
}
Si una clase no implementa todos los métodos requeridos de una interfaz, PHP lanzará un error fatal.
Pruébalo tú mismo
<?php
require_once 'Email.php';
require_once 'SMS.php';
// Leer entradas
$emailAddress = trim(fgets(STDIN));
$phoneNumber = trim(fgets(STDIN));
$messageContent = trim(fgets(STDIN));
// TODO: Crear un objeto Email con la dirección de correo electrónico
// TODO: Crear un objeto SMS con el número de teléfono
// TODO: Llamar a compose() en ambos objetos e imprimir los resultados
// Orden: compose de email, luego compose de SMS
// TODO: Llamar a deliver() en ambos objetos e imprimir los resultados
// Orden: deliver de email, luego deliver de SMS
?>Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosIntroducción a OOPClases vs ObjetosLa palabra clave $thisMétodosPropiedadesConstructor (__construct)Destructor (__destruct)Resumen - Calculadora simple4Herencia
Herencia básicaLa palabra clave parent::Sobrescritura de métodosLa palabra clave finalClases abstractasResumen - Jerarquía de empleados7Encapsulamiento
Público, Protegido, PrivadoModificadores de acceso a fondoGetters y SettersOcultamiento de informaciónPromoción de constructor (8.0)Resumen - Sistema de registros de estudiantes10Conceptos avanzados de POO
Composición vs. HerenciaInyección de dependenciasClases anónimasEnums (PHP 8.1)Fibers (PHP 8.1)Clonación de objetos a fondoGeneradores e Iteradores13Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Repository2Espacios de nombres y Autoloading
Introducción a los espacios de nombresLa palabra clave useEstándar de Autoloading PSR-4Autoloader de ComposerResumen - Proyecto organizado5Interfaces y Contratos
Introducción a las InterfacesImplementación de InterfacesImplementación de Múltiples InterfacesInterfaz vs Clase AbstractaType Hinting con InterfacesResumen - Calculadora de Formas8Métodos mágicos
Introducción a los métodos mágicos__toString y __debugInfo__get, __set, __isset, __unset__call y __callStatic__clone y clonación de objetos__serialize y __unserializeResumen - Colección personalizada3Propiedades de clase
Propiedades de instancia vs. estáticasConstantes en clasesMétodos y propiedades estáticosPropiedades privadas y protegidasPropiedades de solo lectura (PHP 8.1)Resumen - Gestor de cuenta bancaria6Polimorfismo
Sobrescritura de métodos revisadaPolimorfismo mediante interfacesType Hinting y tipos de uniónEnlace estático tardíoResumen - Procesador de pagos9Traits
Introducción a los TraitsUso de múltiples TraitsResolución de conflictos de TraitsMétodos abstractos en TraitsTraits frente a herencia12Patrones de diseño Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón Strategy