Clases abstractas
Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy. Lección 25 de 91.
Una clase abstracta es una clase que no se puede instanciar directamente. Sirve como modelo para otras clases y define métodos que las clases hijas deben implementar. Puedes crear una clase abstracta mediante la palabra clave abstract.
<?php
abstract class Shape {
protected $color;
public function __construct($color) {
$this->color = $color;
}
abstract public function calculateArea();
public function getColor() {
return $this->color;
}
}
class Rectangle extends Shape {
private $width;
private $height;
public function __construct($color, $width, $height) {
parent::__construct($color);
$this->width = $width;
$this->height = $height;
}
public function calculateArea() {
return $this->width * $this->height;
}
}
$rect = new Rectangle("blue", 5, 3);
echo $rect->calculateArea();
Salida:
15La clase Shape declara un método abstracto calculateArea() sin proporcionar una implementación. Cualquier clase que extienda Shape debe implementar este método. Observa que las clases abstractas también pueden contener métodos normales como getColor() que las clases secundarias heredan directamente.
Los métodos abstractos definen lo que una clase hija debe hacer, pero no cómo. Esto garantiza que todas las formas tengan un método calculateArea(), al tiempo que permite que cada forma calcule su área de manera diferente.
Punto clave: Las clases abstractas combinan la estructura de la herencia con requisitos obligatorios. Úsalas cuando quieras compartir código entre clases relacionadas y, al mismo tiempo, asegurarte de que cada clase hija implemente ciertos métodos.
Desafío
FácilConstruyamos un sistema de reproductor multimedia que demuestre cómo las clases abstractas imponen un contrato y, al mismo tiempo, permiten que distintos tipos de medios implementen su propio comportamiento de reproducción.
Organizarás tu código en tres archivos:
Media.php: Define una clase abstractaMediaque sirve como modelo para todos los tipos de medios. Debe tener una propiedad$titleprotegida y un constructor que acepte y establezca el título. Incluye un método abstracto llamadoplay()que las clases derivadas deben implementar. Añade también un método normalgetTitle()que devuelva el título. Este método concreto será heredado por todas las clases derivadas.Song.php: Define una claseSongque extiendaMedia. Incluye el archivo Media al principio. Esta clase añade una propiedad$artist. El constructor debe aceptar el título y el artista: usaparent::__construct()para el título y después establece el artista tú mismo. Implementa el métodoplay()obligatorio para que devuelva"Playing song: [title] by [artist]".Podcast.php: Define una clasePodcastque extiendaMedia. Incluye el archivo Media al principio. Esta clase añade una propiedad$episode(un entero). El constructor debe aceptar el título y el número de episodio: usaparent::__construct()para el título y después establece el episodio. Implementa el métodoplay()obligatorio para que devuelva"Playing podcast: [title] - Episode [episode]".
En main.php, incluye los archivos Song y Podcast. Recibirás cuatro entradas: el título de la canción, el nombre del artista, el título del pódcast y el número de episodio (como una cadena que debes convertir en un entero). Crea un objeto Song y un objeto Podcast con estos valores. Imprime primero el resultado de llamar a play() en la canción y después en el pódcast, cada uno en su propia línea.
Este desafío muestra cómo las clases abstractas definen un contrato: cada tipo de medio debe tener un método play(), pero cada tipo lo implementa de manera diferente. La clase abstracta Media no puede instanciarse directamente; solo existe para proporcionar estructura y funcionalidad compartida a sus clases derivadas.
Pruébalo tú mismo
<?php
require_once 'Song.php';
require_once 'Podcast.php';
// Leer entradas
$songTitle = trim(fgets(STDIN));
$artistName = trim(fgets(STDIN));
$podcastTitle = trim(fgets(STDIN));
$episodeNumber = intval(trim(fgets(STDIN)));
// TODO: Crea un objeto Song con songTitle y artistName
// TODO: Crea un objeto Podcast con podcastTitle y episodeNumber
// TODO: Imprime el resultado de llamar a play() en la canción
// TODO: Imprime el resultado de llamar a play() en el podcast
?>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