Clases anónimas
Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy — lección 58 de 91.
A veces necesitas un objeto simple y único sin la sobrecarga de definir una clase completa. Las clases anónimas te permiten crear objetos sobre la marcha, justo donde los necesitas. Son particularmente útiles cuando se combinan con la inyección de dependencias.
Una clase anónima se define utilizando new class seguido por el cuerpo de la clase:
<?php
$logger = new class {
public function log(string $message): void {
echo "Log: $message";
}
};
$logger->log("Hello!");
Salida:
Log: Hello!Las clases anónimas se vuelven poderosas al implementar interfaces. Esto es perfecto para pruebas o cuando necesitas una implementación rápida sin saturar tu base de código con clases de un solo uso:
<?php
interface Notifier {
public function send(string $message): string;
}
function notify(Notifier $notifier, string $msg): string {
return $notifier->send($msg);
}
$result = notify(new class implements Notifier {
public function send(string $message): string {
return "Sent: $message";
}
}, "Test message");
echo $result;
Salida:
Sent: Test messageLas clases anónimas también pueden extender otras clases, usar traits y aceptar argumentos del constructor. Tienen acceso completo a las características de la POO; simplemente se definen en línea en lugar de en un archivo separado. Úsalas cuando una definición de clase completa sea excesiva, pero aún necesites un comportamiento orientado a objetos.
Desafío
FácilVamos a construir un sistema formateador de datos que demuestre el poder de las clases anónimas. En lugar de crear archivos de clase separados para implementaciones simples y de un solo uso, utilizarás clases anónimas para crear implementaciones rápidas justo donde las necesites.
Organizarás tu código en dos archivos:
FormatterInterface.php— Define una interfaz llamadaFormatterInterfacecon un único métodoformat(string $data): string. Esto establece el contrato que cualquier formateador debe seguir.main.php— Incluye el archivo de la interfaz y crea una claseDataProcessorque utilice inyección de dependencias para aceptar cualquier formateador. La clase debe:- Aceptar un
FormatterInterfaceen su constructor - Tener un método
process(string $data)que delegue en el formateador inyectado y devuelva su resultado
Recibirás dos entradas: un tipo de formato (
"upper"o"reverse") y una cadena para formatear.Basándote en el tipo de formato, crea una clase anónima que implemente
FormatterInterface:- Para
"upper": el métodoformat()debe devolver los datos convertidos a mayúsculas - Para
"reverse": el métodoformat()debe devolver los datos invertidos
Inyecta tu clase anónima en un
DataProcessor, llama aprocess()con la cadena de entrada e imprime el resultado.- Aceptar un
Este enfoque es perfecto cuando necesitas una implementación rápida sin saturar tu base de código con archivos de clase de un solo uso. La clase anónima se crea en línea, implementa la interfaz requerida y puede pasarse a cualquier lugar donde se espere dicha interfaz.
Hoja de referencia
Las clases anónimas te permiten crear objetos sobre la marcha sin definir una clase completa. Se definen utilizando new class seguido del cuerpo de la clase:
<?php
$logger = new class {
public function log(string $message): void {
echo "Log: $message";
}
};
$logger->log("Hello!");
Las clases anónimas pueden implementar interfaces, lo que las hace útiles para la inyección de dependencias y las pruebas:
<?php
interface Notifier {
public function send(string $message): string;
}
function notify(Notifier $notifier, string $msg): string {
return $notifier->send($msg);
}
$result = notify(new class implements Notifier {
public function send(string $message): string {
return "Sent: $message";
}
}, "Test message");
Las clases anónimas admiten todas las características de la POO: pueden extender otras clases, usar traits y aceptar argumentos en el constructor. Úsalas cuando una definición de clase completa sea excesiva pero aún necesites un comportamiento orientado a objetos.
Pruébalo tú mismo
<?php
require_once 'FormatterInterface.php';
// TODO: Crear una clase DataProcessor que:
// - Acepte un FormatterInterface en su constructor
// - Tenga un método process(string $data) que delegue al formateador
// Leer entrada
$formatType = trim(fgets(STDIN));
$inputString = trim(fgets(STDIN));
// TODO: Basado en $formatType ("upper" o "reverse"), crear una clase anónima
// que implemente FormatterInterface
// - Para "upper": format() debe devolver la versión en mayúsculas de los datos
// - Para "reverse": format() debe devolver la versión invertida de los datos
// TODO: Crear un DataProcessor con tu formateador de clase anónima
// Llamar a process() con la cadena de entrada e imprimir el resultado
?>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