De momento hemos visto numerosos ejemplos para trabajar con objetos, pero si nos fijamos bien, todas las clases que hemos usado funcionan de forma independiente, no suelen interactuar con otras clases ni las necesitan.

Desde mi punto de vista una de los posibilidades más potentes que nos ofrece el trabajar con objetos es la herencia de clases. Esto es cuando tenemos una clase “hija” que hereda atributos y métodos de la clase “padre”.

Para tratar de explicarlo mejor, una clase “hija” puede usar los métodos y atributos de la clase “padre” como propios, y también puede definir sus propios métodos y atributos para extender sus funcionalidades más allá de la clase “padre”.

Para heredar una clase tan solo debemos de usar la instrucción extends en la clase hija, quizás si no has trabajado nunca con objetos este concepto suene extraño, pero creo que con un ejemplo se puede comprender mejor:

ClasePadre.php:

<?php 
class ClasePadre { 
    public $atributo = 'Atributo Padre'; 
    public function __construct(){ 
        echo __CLASS__; 
    } 
    public function miMetodo(){ 
        echo "Método Padre"; 
    } 
} 
?>

ClaseHija.php:

<?php 
require_once('ClasePadre.php'); 
class ClaseHija extends ClasePadre { } 
?>

script.php:

<?php 
require_once('ClaseHija.php'); 
$obj = new ClaseHija(); //Imprime: Clase Padre 
echo $obj->atributo; //Imprime: Atributo Padre 
$obj->miMetodo(); //Imprime: Método Padre 
?>

Mira bien el código de script.php, la clase que se ha instanciado es ClaseHija, la cual no contiene en su código ningún método ni atributo propio, sin embargo ha cogido como propios las características de ClasePadre.

Ahora vamos a añadirle métodos propios a nuestra ClaseHija:

ClaseHija.php:

<?php 
require_once('ClasePadre.php'); 
class ClaseHija extends ClasePadre { 
    public function otroMetodo(){ 
        echo "Método hijo"; 
    } 
} 
?>

script.php:

<?php 
require_once('ClaseHija.php'); 
$obj = new ClaseHija(); //Imprime: Clase Padre 
echo $obj->atributo; //Imprime: Atributo Padre 
$obj->miMetodo(); //Imprime: Método Padre 
$obj->otroMetodo(); //Imprime: Método Hijo 
?>

Fácil, ¿verdad?. Hasta aquí hemos visto como una clase hereda las características de su padre, y además puede extender esas características con otras propias de la clase “hija”, pero puede darse el caso de que uno de los métodos de la clase “padre” no nos sea útil, o que necesitemos que haga más cosas o de forma diferente, en ese caso lo que debemos de hacer es simplemente sobrescribir. Para sobrescribir un método o atributo simplemente debemos de declararlo de nuevo dentro de la clase “hija”, de esta forma al llamar al método PHP usará el de la clase hija:

ClaseHija.php:

<?php 
require_once('ClasePadre.php'); 
class ClaseHija extends ClasePadre { 
    //Sobrescribo miMetodo 
    public function miMetodo(){ 
        echo "Método Hijo"; 
    } 
} 
?>

script.php:

<?php 
require_once('ClaseHija.php'); 
$obj = new ClaseHija(); //Imprime: Clase Padre 
echo $obj->atributo; //Imprime: Atributo Padre 
$obj->miMetodo(); //Imprime: Método Hijo 
?>

Como vemos al hacer esto lo que imprime por pantalla el método miMetodo() no es “Método Padre”, si no “Método Hijo”, por lo tanto hemos anulado toda la instrucción que contenía el método padre por el del método hijo. Pero ¿Y si queremos extender la funcionalidad del método padre?, en ese caso al sobrescribir el método debemos de indicar que también ejecute el método padre:

ClaseHija.php:

<?php 
require_once('ClasePadre.php'); 
class ClaseHija extends ClasePadre { 
    //Sobrescribo miMetodo 
    public function miMetodo(){ 
        //Ejecutamos el método padre 
        parent::miMetodo(); 
        //Y añadimos nuestra instrucción 
        echo "Método Hijo"; 
    } 
} 
?>

script.php:

<?php 
require_once('ClaseHija.php'); 
$obj = new ClaseHija(); //Imprime: Clase Padre 
echo $obj->atributo; //Imprime: Atributo Padre 
$obj->miMetodo(); //Imprime: Método Hijo 
?>

Si recordamos, para acceder a los métodos de una clase estática de forma interna se usaba la sentencia self:: acompañada de el método o el atributo, esto como ves se hace de forma similar, salvo que para acceder a atributos o métodos del padre de forma interna se usa parent::, de esta forma podemos determinar en que momento queremos acceder a las funcionalidades de la clase “padre” y cuando no.

El tema de la Herencia es bastante extenso, y no quiero alargarme demasiado, de momento dejo el tema aquí para continuarlo en el próximo artículo.