Ver Mensaje Individual
  #4 (permalink)  
Antiguo 12/03/2014, 08:59
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 11 años, 11 meses
Puntos: 320
Respuesta: APORTE: Emular polimorfismo y sobrecarga tipada de forma simple.

La sobrecarga es una implementacion del polimorfismo, asi como el ejemplo que tu propones es otra forma de implementarlo. El polimorfismo es un concepto abstracto no ligado a una forma de implementarlo.

Bueno, me has sorprendido con la clase abstracta, no me lo esperaba.
Fucione tu codigo y el mio (junto con un par de agregados) y mira lo que salio ¡Se puede usar el polimorfismo como en java! (o casi igual)

Código PHP:
Ver original
  1. <?php
  2.  abstract class OverridableType extends \ReflectionObject
  3.  {
  4.      public static function handleTypehint($errno, $errstr, $errfile, $errline)
  5.      {     
  6.         if (!(error_reporting() & $errno)) { return; }     
  7.         if ($errno == E_RECOVERABLE_ERROR)
  8.         {
  9.             if (preg_match('/^Argument (\d)+ passed to (?:(\w+)::)?(\w+)\(\) must be an instance of (\w+)(.*)/', $errstr, $errmatches))
  10.                 return true;
  11.         }
  12.         return false;
  13.      }
  14.  
  15.     function __construct() { parent::__construct($this); set_error_handler('OverridableType::handleTypehint'); }
  16.  
  17.     function __call($name, $args)
  18.     {
  19.         $cant_args = count($args);
  20.  
  21.         if($cant_args)
  22.         {
  23.             foreach ($this->getMethods() as $method)
  24.             {
  25.                 $parameters = $method->getParameters();
  26.                 if(count($parameters) == $cant_args) // Misma cantidad de parametros.
  27.                 {
  28.                     preg_match("/^$name([0-9]+)/", $method->getShortName(), $coincidencias);
  29.                     if($coincidencias)
  30.                     {
  31.                         // Tienen el mismo numero de argumentos, y el nombre del metodo coincide.
  32.                         preg_match_all('|Parameter #[0-9]+ \[ (<required>*) (.*) \$(.*) \]|U', $method->getParameters()[0]->getDeclaringFunction(), $params);
  33.  
  34.                         $coincidencia = true;
  35.                         foreach($params[2] as $nro => $param)
  36.                         {
  37.                             $type = gettype($args[$nro]);
  38.                             // Verificar que sean del mismo tipo.
  39.                             if(!($type == $param) and !($type == 'object' && ($args[$nro] instanceof $param)))
  40.                             {
  41.                                 $coincidencia = false;
  42.                                 break;
  43.                             }
  44.                         }
  45.                         if($coincidencia)
  46.                             return call_user_func_array([$this, $method->getShortName()], $args);
  47.                     }
  48.                 }
  49.             }
  50.         } else {
  51.             // No vienen parametros. Caso particular.
  52.             return call_user_func_array([$this, $name], $args);
  53.         }
  54.     }
  55.  }


Código PHP:
Ver original
  1. <?php
  2. // Y asi es como se implementa.
  3.  interface Vehicle {
  4.      function run();
  5.  }
  6.  
  7.  class Train implements Vehicle {
  8.     function run() {
  9.         echo 'chu-chu, chu-chu, chu-chu, ...<br />';
  10.     }
  11.  }
  12.  
  13.  class Car implements Vehicle {
  14.      function run() {
  15.          echo 'run, run, run, run, ...<br />';
  16.      }
  17.  }
  18.  
  19.  class Moto implements Vehicle {
  20.      function run() {
  21.          echo 'rrrrrrrrrrrrrrrrrrrr ...<br />';
  22.      }
  23.  }
  24.  
  25.  class Foto {
  26.      function sepia() {
  27.          echo 'me volvi sepia...<br />';
  28.      }
  29.  }
  30.  
  31.  class Test extends OverridableType
  32.  {
  33.     protected function method()
  34.     {
  35.          echo("<br>Hola, no has ingresado nada<br>");
  36.     }
  37.  
  38.     protected function method1(integer $unNumero)
  39.     {
  40.          echo("<br>Hola, has ingresado: $unNumero<br>");
  41.     }
  42.  
  43.     protected function method2(string $miString)
  44.     {
  45.         echo("<br>Hola, has ingresado: '$miString'<br>");
  46.     }
  47.  
  48.     protected function method3(Train $unTren)
  49.     {
  50.         echo("<br>Hola, gracias por el tren<br>");
  51.         $unTren->run();
  52.     }
  53.  
  54.     protected function method4(Car $unAuto)
  55.     {
  56.         echo("<br>Hola, gracias por el auto<br>");
  57.         $unAuto->run();
  58.     }
  59.  
  60.     protected function method5(Vehicle $unVehiculo)
  61.     {
  62.         echo("<br>Hola, gracias por el vehiculo<br>");
  63.         $unVehiculo->run();
  64.     }
  65.  
  66.     protected function method6(object $unObjeto)
  67.     {
  68.         echo("<br>Hola, me diste un objeto: ".get_class($unObjeto).", muchas gracias.<br>");
  69.     }
  70.  }
  71.  
  72.  $test = new Test;
  73.  
  74.  $test->method();
  75.  $test->method(1);
  76.  $test->method('hola');
  77.  $test->method(99, 'hola');
  78.  $test->method('hola', 1);
  79.  $test->method(new Car);
  80.  $test->method(new Train);
  81.  $test->method(new Moto);
  82.  $test->method(new Foto);
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios

Última edición por NSD; 12/03/2014 a las 10:25