Repaso de la sobrescritura de métodos
Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy. Lección 33 de 91.
Ya has aprendido sobre la sobrescritura de métodos en el capítulo sobre herencia. Ahora exploremos cómo se relaciona con el polimorfismo, uno de los conceptos más potentes de la programación orientada a objetos.
El polimorfismo significa «muchas formas». Cuando sobrescribes un método en una clase hija, le das a ese método una forma diferente mientras mantienes el mismo nombre. La magia ocurre cuando trabajas con objetos a través de su tipo padre:
<?php
class Animal {
public function speak() {
return "Some sound";
}
}
class Dog extends Animal {
public function speak() {
return "Woof!";
}
}
class Cat extends Animal {
public function speak() {
return "Meow!";
}
}
function makeAnimalSpeak(Animal $animal) {
return $animal->speak();
}
echo makeAnimalSpeak(new Dog()) . "\n";
echo makeAnimalSpeak(new Cat());
Salida:
Woof!
Meow!La función makeAnimalSpeak() acepta cualquier Animal. No sabe ni le importa si recibe un Dog o un Cat. PHP llama automáticamente al método sobrescrito correcto según el tipo real del objeto en tiempo de ejecución.
Esto es el polimorfismo en acción.
Este enfoque te permite escribir código flexible que funciona con una familia de objetos relacionados sin conocer sus tipos específicos. Más adelante puedes añadir nuevas clases de animales, y la función funcionará con ellas automáticamente.
Punto clave: La sobrescritura de métodos permite el polimorfismo al permitir que distintas clases respondan de manera diferente a la misma llamada a un método, determinado en tiempo de ejecución por el tipo real del objeto.
Desafío
FácilConstruyamos un sistema de instrumentos musicales que demuestre el polimorfismo mediante la sobrescritura de métodos. Crearás una clase base Instrument y dos clases hijas que produzcan cada una su propio sonido único; después usarás una sola función para tocar cualquier instrumento de forma polimórfica.
Organizarás tu código en cuatro archivos:
Instrument.php: Crea una claseInstrumentcon una propiedad$nameprotegida establecida mediante el constructor. Añade un métodoplay()que devuelva"[name] makes a sound". Este será el comportamiento base que las clases hijas sobrescribirán.Guitar.php: Crea una claseGuitarque extiendaInstrument. Incluye el archivo padre. El constructor acepta el nombre y se lo pasa al constructor padre. Sobrescribe el métodoplay()para que devuelva"[name] strums a chord".Drum.php: Crea una claseDrumque extiendaInstrument. Incluye el archivo padre. El constructor acepta el nombre y se lo pasa al constructor padre. Sobrescribe el métodoplay()para que devuelva"[name] beats a rhythm".main.php: Incluye los archivos de Guitar y Drum. Crea una función llamadaperformWithque acepte un parámetroInstrument(con declaración de tipo) y devuelva el resultado de llamar aplay()en él. Esta función demuestra el polimorfismo. Funciona con cualquier tipo de instrumento mediante la declaración de tipo de la clase padre.
Recibirás dos entradas: un nombre para la guitarra y un nombre para el tambor. Crea un Guitar y un Drum con estos nombres. Pasa cada uno a tu función performWith() e imprime los resultados: primero la guitarra y después el tambor, cada uno en su propia línea.
Observa cómo performWith() acepta cualquier Instrument y, aun así, PHP llama automáticamente al método play() sobrescrito correcto según el tipo real del objeto durante la ejecución. ¡Eso es el polimorfismo en acción!
Pruébalo tú mismo
<?php
// Incluir los archivos de instrumentos
require_once 'Guitar.php';
require_once 'Drum.php';
// Leer la entrada
$guitarName = trim(fgets(STDIN));
$drumName = trim(fgets(STDIN));
// TODO: Crea una función llamada performWith que:
// - Acepta un parámetro Instrument (usa type hint: Instrument $instrument)
// - Devuelve el resultado de llamar a play() en el instrumento
// TODO: Crea un Guitar con $guitarName y un Drum con $drumName
// TODO: Pasa cada uno a performWith() e imprime los resultados (guitar primero, luego drum)
?>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 la POO
Archivos externosIntroducción a la POOClases frente a objetosLa palabra clave $thisMétodosPropiedadesConstructor (__construct)Destructor (__destruct)Repaso: calculadora simple4Herencia
Herencia básicaLa palabra clave parent::Sobrescritura de métodosLa palabra clave finalClases abstractasRepaso - Jerarquía de empleados7Encapsulación
Público, protegido, privadoModificadores de acceso en profundidadGetters y settersOcultación de la informaciónPromoción del constructor (8.0)Repaso: sistema de registros de estudiantes10Conceptos avanzados de OOP
Composición vs. herenciaInyección de dependenciasClases anónimasEnums (PHP 8.1)Fibras (PHP 8.1)Análisis profundo de la clonación de objetosGeneradores e iteradores13Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Repository2Namespaces y carga automática
Introducción a los NamespacesLa palabra clave useEstándar de carga automática PSR-4Autoloader de ComposerRepaso: proyecto organizado5Interfaces y contratos
Introducción a las interfacesImplementación de interfacesImplementación de múltiples interfacesInterfaces vs. clase abstractaTipado con interfacesRepaso - 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 __unserializeRepaso: 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)Repaso: gestor de cuentas bancarias6Polimorfismo
Repaso de la sobrescritura de métodosPolimorfismo mediante interfacesAnotaciones de tipo y tipos uniónEnlace estático tardíoRepaso: procesador de pagos9Traits
Introducción a los TraitsUso de múltiples TraitsResolución de conflictos entre TraitsMétodos abstractos en TraitsTraits frente a la herencia12Patrones de diseño, parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón StrategyPractica por tu cuenta: Compilador de PHP online