A lo largo de esta serie de tutoriales hemos visto como crear y trabajar con objetos de diversas formas, pero aun no hemos visto ningún ejemplo en el que una clase interactue con otras mas allá de la herencia.

Lo realmente interesante de la programación orientada a objetos es los fácil que resulta que las clases interactuen entre si, sin necesidad de complicarnos la vida. La forma mas sencilla de relacionar dos clases sería instanciando en la clase ClaseUno un objeto de tipo ClaseDos:

claseuno.php:

<?php 
require_once('clasedos.php'); 

class ClaseUno { 
    public function miMetodo(){ 
        $objDos = new ClaseDos(); 
    } 
} 
?>

clasedos.php:

<?php class ClaseDos { } ?>

index.php:

<?php 
require('claseuno.php'); 
$obj = new ClaseUno(); 
$obj->miMetodo(); 
?>

Como vemos solo hemos de requerir el script de ClaseDos en ClaseUno e instanciar el objeto dentro de uno de sus métodos, pero aun podemos complicar algo más la relación. Imagina que tienes una clase para representar un ordenador, el cual se compone a su vez de otros objetos como puede ser la pantalla, tarjeta grafica, ram, etcétera. Ninguno de esos componentes necesita la clase ordenador, pero la clase ordenador requiere de todos ellos para funcionar correctamente, en este caso podemos declarar varios atributos privados para representar todas sus piezas y luego instanciar en el mediante el método mágico __construct() cada una de ellas:

ordenador.php:

<?php 
require_once('grafica.php'); 
require_once('ram.php'); 
require_once('pantalla.php'); 
require_once('hdd.php'); 

class Ordenador { 
    private $_tarjetaGrafica; 
    private $_memoriaRam; 
    private $_pantalla; 
    private $_discoDuro; 

    public function __construct(){ 
        $this->_pantalla = new Pantalla(); 
        $this->_memoriaRam = new Ram(); 
        $this->_discoDuro = new DiscoDuro(); 
        $this->_tarjetaGrafica = new Grafica(); 
    } 

    public function apagar(){ 
        $this->_pantalla->apagar(); 
        $this->_tarjetaGrafica->ventiladorOff(); 
           $this->_discoDuro->PararDeGirar(); 
        $this->_memoriaRam->limpiar(); 
    } 
} 
?>

De esta forma cada objeto que puede funcionar correctamente por separado son parte esencial de un objeto mucho mas complejo.

Disponemos de otra forma para relacionar nuestras clases, pasando a un método de ClaseUno por parámetro un objeto de ClaseDos, de esta forma el objeto ha sido instanciado fuera de la clase y nosotros nos limitamos simplemente a manipular sus métodos o atributos públicos:

<?php 

class ClaseUno { 
    public function metodoPublico(){ 
        echo "Hola"; 
    } 
} 

class ClaseDos { 
    public function imprimir( $claseUno ){ 
        $claseUno->metodoPublico(); 
    } 
} 

$obj = new ClaseDos(); 
$obj->imprimir( new ClaseUno() ); //Imprime: Hola 
?>

Pero ¿que pasa si le pasamos como parámetros una objeto de clase diferente?, posiblemente nos de un error relacionado con el método que queríamos usar o simplemente la aplicación no funcionará como debería. Para solucionar esto podemos restringir el tipo de objeto que queremos pasar como parámetro añadiendo en el método el nombre de la clase y luego el parámetro:

public function imprimir(ClaseUno $claseUno){}

Esto solo nos permitiría que le pasáramos un objeto de ClaseUno, si intentamos pasar un objeto de otra clase nos tiraría un error tipo “Catchable fatal error: Argument 1 passed to ClaseDos::imprimir() must be an instance of ClaseUno, instance of ClaseTres given …”. Debemos de tener en cuenta que una clase hija que ha heredado de su clase padre tiene dos tipos, el de la clase propia y el de su clase padre, por lo que si restringimos el tipo a la clase padre, podemos pasarle una instancia de esta y una de la clase hija siendo ambas validas, pero al revés no, si restringimos por clase hija no podremos pasarle un objeto de la clase padre.