domingo, 26 de octubre de 2014

PHP (07) POO (07) Sobrecarga de métodos

Seguramente si conoces otros lenguajes de programación como JAVA, este apartado te resulte extraño, ya que PHP sobrecarga los métodos de forma muy diferente a como se hace de forma común a otros lenguajes.
Para ello se utiliza un método llamado __call() al que se le pasa como argumentos; el nombre del método y una lista con los argumentos que este método necesitaría. Este método __call, recibe aquellos métodos que no están definidos de forma independiente, comprobando que estén definidos en su interior.
function __call($metodo, $argumentos)
{
 ...
}  

De este modo imaginemos que queremos introducir una sobrecarga en nuestro método set_name, donde podría introducirse el nombre y los apellidos. Deberemos de crear nuestro método __call en relación a este objetivo.
Lo primero que habría que discernir es si el método pasado por argumento es el correcto, haciéndolo con un if:
function __call($metodo, $argumentos)
{
 if ($metodo = 'set_nombre'){
  ...
 }
}

De este modo controlamos que el método tenga el nombre correcto, pero ahora hay que comprobar el número de argumentos y que se debe de hacer en cada caso, ya que como se ha dicho $argumentos es una lista o array.
function __call($metodo, $argumentos)
{
 if ($metodo = 'set_nombre'){
  if (count($argumentos) == 1){
   $this->nombre = $argumentos[0];
  }
  if (count($argumentos) == 2){
   $this->nombre = $argumentos[0];
   $this->apellido = $argumentos[1];
  }
 }
}

El código comprueba el número de elementos enviados en la lista y dependiendo de cuantos haya crea el objeto con o sin apellido. (Recordemos que los arrays tienen como primer elemento el cero.)

De este modo ahora podemos comprobar como funciona con el siguiente código, donde se crean dos objetos, cada uno con un número diferente de argumentos:
<?php
 class Person
 {
  var $nombre;
  var $apellido;
  var $edad;

  //Funcion __call que recoge el nombre sobrecargado
  function __call($metodo, $argumentos)
  {
   if ($metodo = 'set_nombre'){
    if (count($argumentos) == 1){
     $this->nombre = $argumentos[0];
    }
    if (count($argumentos) == 2){
     $this->nombre = $argumentos[0];
     $this->apellido = $argumentos[1];
    }
   }
  }

  //Aquí comienzan los geters y seters de las propiedades. 
  function get_nombre()
  {
   return $this->nombre;
  }
  function get_apellido()
  {
   return $this->apellido;
  }

  function set_edad($dato)
  {
   $this->edad = $dato;
  }
  
  function get_edad()
  {
   return $this->edad;
  }
 }
 $persona1 = new Person;
 $persona1->set_nombre('Antonio');
 $persona1->set_edad('20');

 $persona2 = new Person;
 $persona2->set_nombre('Manuel', 'Gonzalez');
 $persona2->set_edad('28');

 echo '<h3>Persona1</h3>';
 echo '<p>Mostrando con $persona1->get_nombre: ' . $persona1->get_nombre() . '</p>';
 echo '<p>Mostrando con $persona1->get_edad: ' . $persona1->get_edad() . '</p>';
 echo '<h3>Persona2</h3>';
 echo '<p>Mostrando con $persona2->get_nombre: ' . $persona2->get_nombre() . '</p>';
 echo '<p>Mostrando con $persona2->get_apellido: ' . $persona2->get_apellido() . '</p>';
 echo '<p>Mostrando con $persona2->get_edad: ' . $persona2->get_edad() . '</p>';
?> 

En este código podemos ver como esta incluido nuestro método sobrecargado, y como creamos los dos objetos, el que solo lleva un argumento y el que lleva los dos.
Después solicitamos los datos de ambos objetos y obtenemos el siguiente resultado:

Persona1

Mostrando con $persona1->get_nombre: Antonio
Mostrando con $persona1->get_edad: 20

Persona2

Mostrando con $persona2->get_nombre: Manuel
Mostrando con $persona2->get_apellido: Gonzalez
Mostrando con $persona2->get_edad: 28

Como dije al principio, la forma de realizar los métodos sobrecargados en PHP es algo distinta a como se hace en otros lenguajes, pero no es mucho más difícil, tan solo hay que saber controlar el flujo a través de las instrucciones if.
Pero si reflexionamos sobre esto, llegamos a la conclusión de que con un método __call() se pueden controlar todos los métodos para crear un objeto... pero eso lo dejo en vuestras manos...

No hay comentarios:

Publicar un comentario