W3docs

Herencia en PHP OOP

La herencia en PHP OOP permite crear clases nuevas a partir de existentes con extends, sobrescribir métodos y reutilizar código eficientemente.

La herencia permite que una clase reutilice las propiedades y métodos de otra, de modo que puedes modelar relaciones "es-un" (un Car es un Vehicle) sin copiar código. En PHP se implementa con la palabra clave extends. Este capítulo cubre la sintaxis, cómo funcionan la sobreescritura de métodos y la palabra clave parent, cómo se heredan los constructores, el papel de la visibilidad y la palabra clave final, y un ejemplo completo ejecutable con el que puedes experimentar.

Si eres nuevo en las clases, comienza con Clases y Objetos en PHP y luego vuelve aquí.

¿Qué es la Herencia?

La herencia es la capacidad de definir una nueva clase (la clase hija, subclase o clase derivada) basándose en una existente (la clase padre, superclase o clase base). La clase hija obtiene automáticamente los miembros public y protected del padre y puede:

  • reutilizarlos tal como están,
  • sobreescribirlos con su propia implementación, o
  • agregar propiedades y métodos completamente nuevos.

PHP admite únicamente herencia simple: una clase puede extender exactamente a un padre. Sin embargo, puedes construir una cadenaHatchback extends Car extends Vehicle — y una clase también puede implementar muchas interfaces cuando necesitas comportamiento de más de una fuente.

Beneficios de la Herencia

  • Reutilización — la lógica compartida vive en el padre, por lo que la escribes una sola vez.
  • Mantenibilidad — una corrección en el padre se propaga a todas las subclases; menos duplicación significa menos lugares donde pueden esconderse los errores.
  • Polimorfismo — el código que espera un Vehicle funciona con cualquier subclase, por lo que puedes intercambiar implementaciones libremente.
  • Modelado claro — la jerarquía de clases documenta las relaciones "es-un" de tu dominio.

Sintaxis de Herencia en PHP OOP

Para crear una subclase, escribe extends seguido del nombre de la clase padre:

class ChildClass extends ParentClass {
    // child-specific properties and methods
}

ChildClass ahora tiene todos los miembros public y protected de ParentClass. Ten en cuenta que los miembros private del padre no son accesibles desde la clase hija — usa protected cuando quieras que las subclases accedan a un miembro pero mantenerlo oculto del código externo. Consulta Modificadores de Acceso en PHP para conocer las reglas completas de visibilidad.

Sobreescritura de Métodos del Padre

Una subclase sobreescribe un método del padre declarando un método con el mismo nombre. La versión de la clase hija reemplaza a la del padre para los objetos de esa subclase:

class ParentClass {
    public function displayMessage() {
        echo "Hello from ParentClass";
    }
}

class ChildClass extends ParentClass {
    public function displayMessage() {
        echo "Hello from ChildClass";
    }
}

Llamar al método padre con parent::

Sobreescribir no tiene por qué significar reemplazar — a menudo querrás extender el comportamiento del padre. Usa parent:: para llamar primero a la versión del padre y luego añadir algo:

class ChildClass extends ParentClass {
    public function displayMessage() {
        parent::displayMessage(); // runs the parent's logic
        echo " — and hello from ChildClass";
    }
}

Añadir el atributo #[\Override] (PHP 8.3+) sobre un método le indica a PHP que falle con un error si no sobreescribe realmente a un método padre — una forma económica de detectar errores tipográficos en los nombres de métodos.

Herencia y Extensión de Constructores

Si una clase hija no define su propio constructor, el constructor del padre se hereda y se ejecuta automáticamente. Si la clase hija define uno, el constructor del padre no se llama automáticamente — debes llamarlo explícitamente con parent::__construct(...):

class Vehicle {
    public function __construct(public string $make) {}
}

class Car extends Vehicle {
    public function __construct(string $make, public string $fuelType) {
        parent::__construct($make); // initialise the inherited part
    }
}

Para más información sobre constructores, consulta Constructor en PHP.

Prevenir la Sobreescritura con final

Marca un método como final para evitar que las subclases lo sobreescriban, o marca toda una clase como final para evitar que sea extendida:

class PaymentBase {
    final public function transactionId(): string {
        return 'TX-' . uniqid();
    }
}

Esto es útil para lógica que debe comportarse de manera idéntica en todas partes. Consulta Palabra clave final en PHP para más detalles. Cuando el padre debe definir la firma de un método pero forzar a cada clase hija a proporcionar el cuerpo, usa una clase abstracta en su lugar.

Ejemplo de Herencia en PHP OOP

Aquí tienes un programa completo y ejecutable. Una clase base Vehicle contiene los datos comunes, y una subclase Car agrega una propiedad fuelType y extiende displayDetails() mediante parent:::

<?php

class Vehicle
{
    public function __construct(
        protected string $make,
        protected string $model,
        protected int $year
    ) {}

    public function displayDetails(): void
    {
        echo "Make: {$this->make}\n";
        echo "Model: {$this->model}\n";
        echo "Year: {$this->year}\n";
    }
}

class Car extends Vehicle
{
    public function __construct(
        string $make,
        string $model,
        int $year,
        protected string $fuelType
    ) {
        parent::__construct($make, $model, $year);
    }

    public function displayDetails(): void
    {
        parent::displayDetails();           // reuse the parent's output
        echo "Fuel Type: {$this->fuelType}\n"; // then add our own
    }
}

$car = new Car('Toyota', 'Corolla', 2023, 'Hybrid');
$car->displayDetails();

Salida:

Make: Toyota
Model: Corolla
Year: 2023
Fuel Type: Hybrid

Car hereda make, model y year (declarados como protected, para que la subclase pueda usarlos), reutiliza el displayDetails() del padre a través de parent::, y agrega su propia línea de fuelType.

Errores Comunes

  • private no se hereda. Una propiedad private del padre es invisible para la clase hija. Usa protected si las subclases la necesitan.
  • Los constructores no se encadenan automáticamente cuando la clase hija define el suyo propio — siempre llama a parent::__construct() tú mismo.
  • PHP no tiene herencia múltiple. Una clase extiende a un solo padre; usa interfaces o traits para compartir comportamiento de múltiples fuentes.
  • La sobreescritura ignora los errores tipográficos silenciosamente antes de PHP 8.3 — un nombre de método mal escrito simplemente crea un nuevo método en lugar de sobreescribir. Añade #[\Override] para mayor seguridad.

Conclusión

La herencia permite que una subclase reutilice, sobreescriba y extienda los miembros de una clase padre mediante la palabra clave extends, con parent:: dando acceso a la implementación original. Combinada con modificadores de visibilidad, constructores y final, es la columna vertebral de la reutilización de código y el polimorfismo en PHP OOP. A continuación, explora las clases abstractas y las interfaces para diseñar jerarquías de clases más limpias.

Práctica

Práctica
En la herencia en PHP, ¿cuáles de las siguientes afirmaciones son verdaderas?
En la herencia en PHP, ¿cuáles de las siguientes afirmaciones son verdaderas?
Was this page helpful?