PHP
Tutorial PHP: Herencia
PHP: Aprende sobre clases padre e hijo, herencia, y sobrescritura de métodos para mejorar la reutilización de código.
Aprende PHP GRATIS y certifícateClases padre e hijo
En la programación orientada a objetos, las clases padre e hijo son fundamentales para establecer relaciones de herencia entre clases. Una clase padre (o superclase) define propiedades y métodos que pueden ser heredados por una o varias clases hijo (o subclases), permitiendo así la reutilización y organización eficiente del código.
Por ejemplo, considera una clase Vehiculo
que encapsula atributos y comportamientos comunes a todos los vehículos, como mover()
o detener()
. Las clases hijo como Coche
y Moto
pueden derivar de Vehiculo
, heredando estas propiedades y métodos, y agregando características específicas.
La herencia facilita la extensibilidad del código al permitir que las clases hijo amplíen o modifiquen el comportamiento de la clase padre. Esto es útil para crear estructuras jerárquicas claras y para implementar funcionalidades especializadas sin duplicar código.
Es importante destacar que en PHP una clase hijo solo puede heredar de una única clase padre, ya que no se admite la herencia múltiple directa. Sin embargo, se pueden utilizar traits para incorporar funcionalidades adicionales y simular cierto comportamiento de herencia múltiple.
La relación entre clases padre e hijo es esencial para aplicar principios como el principio de sustitución de Liskov, que permite utilizar objetos de la clase hijo donde se espera un objeto de la clase padre, manteniendo la cohesión y flexibilidad del código.
Uso de la palabra clave extends
En PHP, la palabra clave extends
se emplea para indicar que una clase hereda de otra existente. Esto permite que la nueva clase (clase hijo) adquiera las propiedades y métodos de la clase padre, facilitando la reutilización y organización del código.
Por ejemplo, supongamos una clase Animal
que define comportamientos generales:
<?php
class Animal
{
protected $nombre;
public function __construct($nombre)
{
$this->nombre = $nombre;
}
public function comer()
{
echo "$this->nombre está comiendo.\n";
}
}
Si queremos crear una clase Perro
que herede de Animal
, utilizamos extends
:
class Perro extends Animal
{
public function ladrar()
{
echo "$this->nombre está ladrando.\n";
}
}
Al hacerlo, Perro
hereda el constructor y el método comer()
de Animal
. Podemos crear una instancia de Perro
y utilizar ambos métodos:
$miPerro = new Perro("Firulais");
$miPerro->comer();
$miPerro->ladrar();
La salida será:
Firulais está comiendo.
Firulais está ladrando.
La herencia con extends
permite que la clase hijo amplíe o especialice el comportamiento de la clase padre. Además, es posible acceder a los métodos y propiedades protegidas de la clase padre desde la clase hijo, manteniendo el encapsulamiento.
Es importante recordar que en PHP una clase solo puede extender de una única clase (herencia simple). Sin embargo, se pueden combinar varias funcionalidades utilizando traits, que se verán en secciones posteriores.
Al utilizar extends
, asegúrate de que la clase padre esté definida antes de la clase hijo. La correcta aplicación de extends
es esencial para construir jerarquías de clases y aprovechar al máximo la programación orientada a objetos en PHP.
Sobrescritura de métodos
La sobrescritura de métodos es un mecanismo en programación orientada a objetos que permite a una clase hijo redefinir un método heredado de su clase padre. Esto es útil cuando el comportamiento definido en la clase padre no encaja completamente con las necesidades de la clase hijo, y se requiere una implementación específica.
Al sobrescribir un método, el nombre y la firma deben coincidir exactamente con los del método en la clase padre. La clase hijo puede alterar el comportamiento, extendiendo o reemplazando la funcionalidad original.
Por ejemplo, considera una clase padre Empleado
:
<?php
class Empleado
{
protected $nombre;
public function __construct($nombre)
{
$this->nombre = $nombre;
}
public function calcularSalario()
{
echo "El salario de $this->nombre es base.\n";
}
}
Ahora, una clase hijo Gerente
puede sobrescribir el método calcularSalario()
para reflejar una estructura salarial diferente:
class Gerente extends Empleado
{
public function calcularSalario()
{
echo "El salario de $this->nombre incluye bonificaciones.\n";
}
}
Al crear instancias de ambas clases, observarás diferentes comportamientos:
$empleado = new Empleado("Ana");
$empleado->calcularSalario(); // Salida: El salario de Ana es base.
$gerente = new Gerente("Luis");
$gerente->calcularSalario(); // Salida: El salario de Luis incluye bonificaciones.
En este caso, la clase Gerente
ha sobrescrito el método calcularSalario()
para proporcionar una implementación específica.
Es posible también llamar al método original de la clase padre utilizando parent::
. Esto permite conservar el comportamiento original y añadir funcionalidades adicionales:
class Gerente extends Empleado
{
public function calcularSalario()
{
parent::calcularSalario();
echo "$this->nombre recibe beneficios extra.\n";
}
}
La salida ahora será:
El salario de Luis es base.
Luis recibe beneficios extra.
La sobrescritura de métodos es esencial para aplicar el polimorfismo, permitiendo que objetos de distintas clases respondan de manera diferente al mismo método. Además, mejora la flexibilidad y extensibilidad del código al adaptar comportamientos heredados a necesidades específicas.
Al sobrescribir métodos, es importante respetar la visibilidad del método original. Si el método en la clase padre es public
, el método sobrescrito debe ser public
también. Reducir la visibilidad puede generar errores y violar los principios de la herencia.
Además, a partir de PHP 7.4, es posible especificar tipos de retorno y parámetros en los métodos. Al sobrescribir un método, los tipos declarados deben ser compatibles con los del método original:
class Empleado
{
public function obtenerID(): int
{
return 123;
}
}
class Gerente extends Empleado
{
public function obtenerID(): int
{
return 456;
}
}
Mantener la coherencia en los tipos garantiza que la sobrescritura se realice correctamente y que el código sea robusto y fácil de mantener.
Uso de parent::
En PHP, parent:: es una sintaxis que permite a una clase hijo acceder a métodos y propiedades de su clase padre. Esto es especialmente útil cuando la clase hijo ha sobrescrito un método y necesita invocar la implementación original de la clase padre.
Por ejemplo, al sobrescribir el constructor en una clase hijo, es común llamar al constructor de la clase padre para asegurarse de que todas las propiedades heredadas se inicializan correctamente:
<?php
class Vehiculo
{
protected $marca;
public function __construct($marca)
{
$this->marca = $marca;
}
}
class Coche extends Vehiculo
{
private $modelo;
public function __construct($marca, $modelo)
{
parent::__construct($marca);
$this->modelo = $modelo;
}
}
En este ejemplo, la clase Coche
extiende de Vehiculo
y sobrescribe el método __construct()
. Mediante parent::__construct($marca);, se invoca el constructor de la clase padre, inicializando la propiedad $marca.
Además de constructores, parent:: se utiliza para acceder a métodos sobrescritos en la clase hijo:
class Empleado
{
protected $nombre;
public function __construct($nombre)
{
$this->nombre = $nombre;
}
public function presentar()
{
echo "Hola, soy $this->nombre.\n";
}
}
class Gerente extends Empleado
{
public function presentar()
{
parent::presentar();
echo "Soy el gerente de la empresa.\n";
}
}
$gerente = new Gerente("Laura");
$gerente->presentar();
La salida será:
Hola, soy Laura.
Soy el gerente de la empresa.
Aquí, parent::presentar(); permite que el método presentar()
del Gerente mantenga la presentación básica definida en la clase Empleado
, y añada información específica.
También es posible utilizar parent:: para acceder a propiedades protegidas o públicas de la clase padre:
class Animal
{
protected $especie = "Animal genérico";
public function obtenerEspecie()
{
return $this->especie;
}
}
class Perro extends Animal
{
protected $especie = "Perro";
public function describir()
{
echo "Este es un " . parent::obtenerEspecie() . ".\n";
echo "Más específicamente, es un $this->especie.\n";
}
}
$perro = new Perro();
$perro->describir();
La salida será:
Este es un Animal genérico.
Más específicamente, es un Perro.
En este caso, parent::obtenerEspecie(); invoca el método de la clase padre para obtener la especie general, mientras que $this->especie
obtiene la propiedad sobrescrita en la clase hijo.
Es importante notar que parent:: solo puede acceder a miembros que sean públicos o protegidos en la clase padre. No es posible acceder a propiedades o métodos privados, ya que estos no se heredan.
Cuando se trabajan con métodos estáticos, parent:: también es aplicable:
class Logger
{
public static function log($mensaje)
{
echo "Log: $mensaje\n";
}
}
class FileLogger extends Logger
{
public static function log($mensaje)
{
parent::log($mensaje);
// Código adicional para escribir en un archivo
echo "El mensaje ha sido guardado en el archivo.\n";
}
}
FileLogger::log("Mensaje de prueba");
La salida será:
Log: Mensaje de prueba
El mensaje ha sido guardado en el archivo.
Aquí, parent::log($mensaje); llama al método estático de la clase Logger
, aprovechando su funcionalidad antes de añadir operaciones específicas de FileLogger
.
Además, en contextos donde varias clases comparten una jerarquía de herencia, parent:: siempre se refiere a la clase inmediatamente superior. Si existe una cadena de herencia más extensa, parent:: no accederá a métodos o propiedades más allá de la clase padre directa.
Otra aplicación de parent:: es en combinación con los métodos mágicos como __call()
o __toString()
. Si se sobrescriben en la clase hijo, se puede utilizar parent::__call() para mantener parte del comportamiento original:
class Base
{
public function __call($nombre, $argumentos)
{
echo "Llamando al método $nombre en la clase Base.\n";
}
}
class Derivada extends Base
{
public function __call($nombre, $argumentos)
{
echo "Llamando al método $nombre en la clase Derivada.\n";
parent::__call($nombre, $argumentos);
}
}
$obj = new Derivada();
$obj->metodoInexistente();
La salida será:
Llamando al método metodoInexistente en la clase Derivada.
Llamando al método metodoInexistente en la clase Base.
De esta forma, se puede extender la funcionalidad de los métodos mágicos sin perder la lógica implementada en la clase padre.
Finalmente, es esencial comprender que el uso adecuado de parent:: promueve la reutilización de código y el cumplimiento de principios de buen diseño orientado a objetos. Al aprovechar las implementaciones existentes en la clase padre, se evita la duplicación y se facilita el mantenimiento y evolución del código.
Todas las lecciones de PHP
Accede a todas las lecciones de PHP y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Php
Introducción Y Entorno
Instalación Y Primer Programa De Php
Introducción Y Entorno
Tipos De Datos, Variables Y Constantes
Sintaxis
Operadores Y Expresiones
Sintaxis
Estructuras De Control
Sintaxis
Funciones Y Llamada De Funciones
Sintaxis
Cadenas De Texto Y Manipulación
Sintaxis
Manejo De Números
Sintaxis
Manejo De Fechas Y Tiempo
Sintaxis
Manejo De Arrays
Sintaxis
Introducción A La Poo En Php
Programación Orientada A Objetos
Clases Y Objetos
Programación Orientada A Objetos
Constructores Y Destructores
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Encapsulación
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Interfaces
Programación Orientada A Objetos
Traits
Programación Orientada A Objetos
Namespaces
Programación Orientada A Objetos
Autoloading De Clases
Programación Orientada A Objetos
Manejo De Errores Y Excepciones
Programación Orientada A Objetos
Manejo De Archivos
Programación Orientada A Objetos
Patrones De Diseño
Programación Orientada A Objetos
Introducción A Los Formularios En Php
Formularios
Procesamiento De Datos De Formularios
Formularios
Manejo De Archivos En Formularios
Formularios
Redirecciones Y Retroalimentación Al Usuario
Formularios
Formularios Dinámicos Y Separación De Lógica
Formularios
Introducción A La Persistencia En Php
Persistencia
Conexión A Bases De Datos
Persistencia
Consultas Y Operaciones Crud
Persistencia
Gestión De Transacciones
Persistencia
Manejo De Errores Y Excepciones En Base De Datos
Persistencia
Patrones De Acceso A Datos
Persistencia
Concepto De Sesiones En Php
Sesiones Y Cookies
Configuración De Sesiones
Sesiones Y Cookies
Cookies
Sesiones Y Cookies
Manejo Avanzado De Sesiones Y Cookies
Sesiones Y Cookies
Principales Vulnerabilidades En Php
Seguridad
Seguridad En Formularios Y Entrada De Datos
Seguridad
Protección Frente A Inyección Sql
Seguridad
Gestión De Contraseñas Y Cifrado
Seguridad
Seguridad En Sesiones Y Cookies
Seguridad
Configuraciones De Php Para Seguridad
Seguridad
Introducción Al Testing En Php
Testing
Phpunit
Testing
Cobertura De Código En Testing
Testing
Test Doubles (Mocks, Stubs, Fakes, Spies)
Testing
Pruebas De Integración Y Funcionales
Testing
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender el concepto de herencia en programación orientada a objetos.
- Aprender a utilizar la palabra clave
extends
en PHP. - Conocer la sobrescritura de métodos y su aplicación práctica.
- Identificar cómo
parent::
facilita la accesibilidad a métodos heredados. - Explorar ejemplos claros de aplicación de herencia en PHP.