Herencia
La herencia permite crear clases basadas en otras existentes, heredando sus propiedades y metodos. Esto promueve la reutilizacion de codigo y modela relaciones "es un/una".
¿Que es la herencia?
La herencia modela relaciones jerarquicas. Un
Perro es un
Animal, un Gerente
es un Empleado. La
clase hija hereda todo de la clase padre y puede
agregar o modificar comportamiento.
<?php
declare(strict_types=1);
class Animal
{
protected string $nombre;
public function __construct(string $nombre)
{
$this->nombre = $nombre;
}
public function hacerSonido(): string
{
return 'Algun sonido';
}
}
class Perro extends Animal
{
public function hacerSonido(): string
{
return 'Guau!';
}
public function buscarPelota(): string
{
return "{$this->nombre} busca la pelota";
}
}
$perro = new Perro('Rex');
echo $perro->hacerSonido(); // Guau!
echo $perro->buscarPelota(); // Rex busca la pelota
extends y parent::
Usamos extends para heredar y
parent::
para llamar a metodos de la clase padre:
<?php
declare(strict_types=1);
class Empleado
{
protected string $nombre;
protected float $salario;
public function __construct(string $nombre, float $salario)
{
$this->nombre = $nombre;
$this->salario = $salario;
}
public function getSalario(): float
{
return $this->salario;
}
}
class Gerente extends Empleado
{
private float $bono;
public function __construct(string $nombre, float $salario, float $bono)
{
parent::__construct($nombre, $salario); // Llamar constructor padre
$this->bono = $bono;
}
public function getSalario(): float
{
return parent::getSalario() + $this->bono; // Extender funcionalidad
}
}
$empleado = new Empleado('Ana', 2000);
echo $empleado->getSalario(); // 2000
$gerente = new Gerente('Luis', 3000, 500);
echo $gerente->getSalario(); // 3500
Siempre llama a
parent::__construct()
cuando la clase padre tiene constructor.
Asi aseguras que se inicialice
correctamente.
Sobrescritura de métodos
La clase hija puede sobrescribir metodos del padre para cambiar su comportamiento:
<?php
declare(strict_types=1);
class Vehiculo
{
protected string $marca;
public function __construct(string $marca)
{
$this->marca = $marca;
}
public function arrancar(): string
{
return 'Vehiculo arrancando';
}
}
class Coche extends Vehiculo
{
public function arrancar(): string
{
return "El coche {$this->marca} arranca con llave";
}
}
class Moto extends Vehiculo
{
public function arrancar(): string
{
return "La moto {$this->marca} arranca con boton";
}
}
$coche = new Coche('Toyota');
$moto = new Moto('Honda');
echo $coche->arrancar(); // El coche Toyota arranca con llave
echo $moto->arrancar(); // La moto Honda arranca con boton
protected vs private
Recuerda: protected es accesible en
clases hijas, private no:
<?php
declare(strict_types=1);
class Padre
{
protected string $protegido = 'accesible';
private string $privado = 'inaccesible';
}
class Hijo extends Padre
{
public function mostrar(): void
{
echo $this->protegido; // OK
// echo $this->privado; // Error: no accesible
}
}
Ejemplo practico: Sistema de formas
<?php
declare(strict_types=1);
class Forma
{
protected string $color;
public function __construct(string $color)
{
$this->color = $color;
}
public function getArea(): float
{
return 0.0;
}
}
class Rectangulo extends Forma
{
private float $ancho;
private float $alto;
public function __construct(float $ancho, float $alto, string $color)
{
parent::__construct($color);
$this->ancho = $ancho;
$this->alto = $alto;
}
public function getArea(): float
{
return $this->ancho * $this->alto;
}
}
class Circulo extends Forma
{
private float $radio;
public function __construct(float $radio, string $color)
{
parent::__construct($color);
$this->radio = $radio;
}
public function getArea(): float
{
return M_PI * $this->radio ** 2;
}
}
$rectangulo = new Rectangulo(10, 5, 'azul');
$circulo = new Circulo(3, 'rojo');
echo $rectangulo->getArea(); // 50
echo $circulo->getArea(); // 28.27...
PHP solo permite heredar de una clase. Para reutilizar codigo de multiples fuentes, veremos traits e interfaces en proximas lecciones.
Ejercicios
Ejercicio 1: Vehiculos
Crea una clase base
Vehiculo con
marca,
modelo y metodo
describir(). Crea clases
Coche (con
puertas) y
Moto (con
cilindrada) que
sobrescriban describir().
Ver solucion
<?php
declare(strict_types=1);
class Vehiculo
{
protected string $marca;
protected string $modelo;
public function __construct(string $marca, string $modelo)
{
$this->marca = $marca;
$this->modelo = $modelo;
}
public function describir(): string
{
return "Vehiculo: {$this->marca} {$this->modelo}";
}
}
class Coche extends Vehiculo
{
private int $puertas;
public function __construct(string $marca, string $modelo, int $puertas)
{
parent::__construct($marca, $modelo);
$this->puertas = $puertas;
}
public function describir(): string
{
return "Coche: {$this->marca} {$this->modelo} ({$this->puertas} puertas)";
}
}
class Moto extends Vehiculo
{
private int $cilindrada;
public function __construct(string $marca, string $modelo, int $cilindrada)
{
parent::__construct($marca, $modelo);
$this->cilindrada = $cilindrada;
}
public function describir(): string
{
return "Moto: {$this->marca} {$this->modelo} ({$this->cilindrada}cc)";
}
}
$coche = new Coche('Toyota', 'Corolla', 4);
$moto = new Moto('Honda', 'CBR', 600);
echo $coche->describir(); // Coche: Toyota Corolla (4 puertas)
echo $moto->describir(); // Moto: Honda CBR (600cc)
Ejercicio 2: Empleados
Crea Empleado con
nombre y
salarioBase. Crea
Desarrollador que agregue
lenguaje y un bono del 20%
al salario. Crea
Disenador con
herramienta
y bono del 15%.
Ver solucion
<?php
declare(strict_types=1);
class Empleado
{
protected string $nombre;
protected float $salarioBase;
public function __construct(string $nombre, float $salarioBase)
{
$this->nombre = $nombre;
$this->salarioBase = $salarioBase;
}
public function getSalario(): float
{
return $this->salarioBase;
}
public function getNombre(): string
{
return $this->nombre;
}
}
class Desarrollador extends Empleado
{
private string $lenguaje;
public function __construct(string $nombre, float $salarioBase, string $lenguaje)
{
parent::__construct($nombre, $salarioBase);
$this->lenguaje = $lenguaje;
}
public function getSalario(): float
{
return parent::getSalario() * 1.20; // +20% bono
}
public function getLenguaje(): string
{
return $this->lenguaje;
}
}
class Disenador extends Empleado
{
private string $herramienta;
public function __construct(string $nombre, float $salarioBase, string $herramienta)
{
parent::__construct($nombre, $salarioBase);
$this->herramienta = $herramienta;
}
public function getSalario(): float
{
return parent::getSalario() * 1.15; // +15% bono
}
}
$dev = new Desarrollador('Ana', 3000, 'PHP');
$dis = new Disenador('Luis', 2800, 'Figma');
echo $dev->getSalario(); // 3600 (3000 + 20%)
echo $dis->getSalario(); // 3220 (2800 + 15%)
Ejercicio 3: Cuentas bancarias
Crea Cuenta con
saldo y metodos
depositar() y
retirar(). Crea
CuentaAhorro que agregue
interes al depositar y
CuentaCorriente que permita
sobregiro hasta -500.
Ver solucion
<?php
declare(strict_types=1);
class Cuenta
{
protected float $saldo;
public function __construct(float $saldoInicial = 0)
{
$this->saldo = $saldoInicial;
}
public function depositar(float $cantidad): void
{
if ($cantidad > 0) {
$this->saldo += $cantidad;
}
}
public function retirar(float $cantidad): bool
{
if ($cantidad > 0 && $cantidad <= $this->saldo) {
$this->saldo -= $cantidad;
return true;
}
return false;
}
public function getSaldo(): float
{
return $this->saldo;
}
}
class CuentaAhorro extends Cuenta
{
private float $tasaInteres;
public function __construct(float $saldoInicial = 0, float $tasaInteres = 0.02)
{
parent::__construct($saldoInicial);
$this->tasaInteres = $tasaInteres;
}
public function depositar(float $cantidad): void
{
if ($cantidad > 0) {
$interes = $cantidad * $this->tasaInteres;
$this->saldo += $cantidad + $interes;
}
}
}
class CuentaCorriente extends Cuenta
{
private float $limiteDescubierto = 500;
public function retirar(float $cantidad): bool
{
if ($cantidad > 0 && ($this->saldo - $cantidad) >= -$this->limiteDescubierto) {
$this->saldo -= $cantidad;
return true;
}
return false;
}
}
$ahorro = new CuentaAhorro(1000, 0.05);
$ahorro->depositar(100);
echo $ahorro->getSaldo(); // 1105 (1000 + 100 + 5% de 100)
$corriente = new CuentaCorriente(200);
$corriente->retirar(500); // Permite, sobregiro hasta -500
echo $corriente->getSaldo(); // -300
¿Has encontrado un error o tienes una sugerencia para mejorar esta leccion?
Escribenos¿Te está gustando el curso?
Tenemos cursos premium con proyectos reales y soporte personalizado.
Descubrir cursos premium