Menu
Coddy logo textTech

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 un plano para otras clases, definiendo métodos que las clases hijas deben implementar. Se crea una clase abstracta utilizando 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();

Resultado:

15

La 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 regulares como getColor() que las clases hijas heredan directamente.

Los métodos abstractos definen lo que una clase hija debe hacer, pero no cómo. Esto asegura que todas las formas tengan un método calculateArea() mientras 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, asegurar que cada clase hija implemente ciertos métodos.

challenge icon

Desafío

Fácil

Construyamos un sistema de reproductor de medios que demuestre cómo las clases abstractas imponen un contrato mientras permiten que diferentes tipos de medios implementen su propio comportamiento de reproducción.

Organizarás tu código en tres archivos:

  • Media.php — Define una clase abstracta Media que sirva como plano para todos los tipos de medios. Debe tener una propiedad protegida $title y un constructor que acepte y establezca el título. Incluye un método abstracto llamado play() que las clases hijas deben implementar. También añade un método regular getTitle() que devuelva el título — este método concreto será heredado por todas las clases hijas.
  • Song.php — Define una clase Song que extienda de Media. Incluye el archivo Media al principio. Esta clase añade una propiedad $artist. El constructor debe aceptar el título y el artista — usa parent::__construct() para el título, luego establece el artista tú mismo. Implementa el método play() requerido para que devuelva "Playing song: [title] by [artist]".
  • Podcast.php — Define una clase Podcast que extienda de Media. 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 — usa parent::__construct() para el título, luego establece el episodio. Implementa el método play() requerido para que devuelva "Playing podcast: [title] - Episode [episode]".

En main.php, incluye tanto el archivo de Song como el de Podcast. Recibirás cuatro entradas: el título de la canción, el nombre del artista, el título del podcast y el número de episodio (como una cadena para convertir a entero). Crea un objeto Song y un objeto Podcast con estos valores. Imprime el resultado de llamar a play() en la canción primero, luego en el podcast, 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 ser instanciada directamente; solo existe para proporcionar estructura y funcionalidad compartida a sus hijos.

Hoja de referencia

Una clase abstracta es una clase que no se puede instanciar directamente. Sirve como un plano para otras clases, definiendo métodos que las clases hijas deben implementar. Utilice la palabra clave abstract para crear una clase abstracta.

abstract class Shape {
    protected $color;
    
    public function __construct($color) {
        $this->color = $color;
    }
    
    abstract public function calculateArea();
    
    public function getColor() {
        return $this->color;
    }
}

Las clases hijas deben implementar todos los métodos abstractos:

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;
    }
}

Características clave:

  • Las clases abstractas no se pueden instanciar directamente
  • Los métodos abstractos no tienen implementación en la clase abstracta
  • Las clases hijas deben implementar todos los métodos abstractos
  • Las clases abstractas pueden contener tanto métodos abstractos como regulares
  • Los métodos regulares en las clases abstractas son heredados por las clases hijas

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: Crear un objeto Song con songTitle y artistName

// TODO: Crear un objeto Podcast con podcastTitle y episodeNumber

// TODO: Imprimir el resultado de llamar a play() en la canción

// TODO: Imprimir el resultado de llamar a play() en el podcast

?>
quiz iconPonte a prueba

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