Foros del Web » Programando para Internet » PHP »

APORTE: Emular polimorfismo y sobrecarga tipada de forma simple.

Estas en el tema de APORTE: Emular polimorfismo y sobrecarga tipada de forma simple. en el foro de PHP en Foros del Web. Hola gente, arme este humilde script que utiliza la herencia de una clase generica llamada polimorfismo para realizar este proceso y lo comparto por si ...
  #1 (permalink)  
Antiguo 11/03/2014, 23:25
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
APORTE: Emular polimorfismo y sobrecarga tipada de forma simple.

Hola gente, arme este humilde script que utiliza la herencia de una clase generica llamada polimorfismo para realizar este proceso y lo comparto por si alguien le interesa.

se puede sobrecargar por cantidad de argumentos, por cantidad y tipo, por cantidad, tipo y clase (si el parametro es un objeto).

aqui el codigo:
Código PHP:
Ver original
  1. <?php
  2.  // Clase padre heredable, es la que realiza la emulacion.
  3.  class polimorfismo
  4.  {
  5.     /*
  6.      * @param string $metodo        El nombre del metodo que se va a sobrecargar.
  7.      * @param array  $params        Los parametros con los que se llamo el metodo.
  8.      * @param bool   $tipado        Indica si se va a discriminar por el tipo de los argumentos.
  9.      * @param bool   $instanciado   Indica si se va a discriminar por el tipo de clase de los parametros (cuando sea un objeto).
  10.     */
  11.     protected function chk_polimorfismo($metodo, $params, $tipado = false, $instanciado = false)
  12.     {
  13.         $metodo .= count($params);
  14.         if($tipado && $params)
  15.         {
  16.             foreach($params as $param)
  17.                 $metodo .= '_'.(gettype($param) == 'object' ? ($instanciado ? get_class($param) : 'object') : gettype($param));
  18.         }
  19.        
  20.         if(method_exists($this, $metodo))
  21.             call_user_func_array(array($this,$metodo),$params);
  22.     }  
  23.  }
  24.  
  25.  // Las clases que emulen el polimorfismo deben heredar.
  26.  class test_polimorfico extends polimorfismo
  27.  {
  28.     // Al metodo publico a sobrecargar, se le asigna la llamada al metodo protected de la clase emuladora.
  29.     public function sobrecargado() { $this->chk_polimorfismo('test', func_get_args(), true); } 
  30.    
  31.     // Se crean los metodos protected que seran llamados por la sobrecarga.
  32.     // Se los pone como protected para que no sean vistos desde afuera y simulen un polimorfismo mas clasico.
  33.     protected function test0() // 0 argumentos.
  34.     {
  35.         echo('<br>Hola, no me pasaron ningun parametro.');
  36.     }
  37.    
  38.     protected function test1_string($string) // Un argumento, de tipo string
  39.     {
  40.         echo('<br>Hola, me pasaste este string: '.$string);
  41.     }
  42.    
  43.     protected function test1_integer($integer) // Un argumento, de tipo integer
  44.     {
  45.         echo('<br>Hola, me pasaste este integer: '.$integer);
  46.     }
  47.    
  48.     protected function test2_integer_string($integer, $string)
  49.     {
  50.         echo('<br>Hola, me pasaste este integer: '.$integer.' y este string: '.$string);
  51.     }
  52.    
  53.     protected function test2_string_integer($string, $integer)
  54.     {
  55.         echo('<br>Hola, me pasaste este string: '.$integer.' y este integer: '.$string);
  56.     }
  57.  }
  58.  
  59.  $test = new test_polimorfico();
  60.  $test->sobrecargado();
  61.  $test->sobrecargado('prueba');
  62.  $test->sobrecargado(5);
  63.  $test->sobrecargado(5, 'prueba');
  64.  $test->sobrecargado('prueba', 5);
  65.  $test->sobrecargado('2');
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #2 (permalink)  
Antiguo 12/03/2014, 02:51
lolainas
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: APORTE: Emular polimorfismo y sobrecarga tipada de forma simple.

Buen aporte amigo, me gusta la idea.

Apuntes:

1. chk_polimorfismo debería devolver el resultado de la ejecución del método sobrecargado.

2. Uso de métodos mágicos de PHP, en concreto '__call', imaginate en un proyecto grande llamando a
Código PHP:
Ver original
  1. Customer->sobrecarga('getLastOrder', array('param1', 'param2', 'param3'), true, true);
3. Aprovecha la reflexión para solucionar este problema:

Código PHP:
Ver original
  1. <?php
  2.  
  3. abstract class Overridable extends \ReflectionObject {
  4.  
  5.     private function compare(array $params, array $args) {
  6.         if (count($params) != count($args))
  7.             return false;
  8.         foreach ($params as $param)
  9.             if ($param->getName() != gettype(each($args)[1]))
  10.                 return false;
  11.         return true;
  12.     }
  13.  
  14.     function __construct() {
  15.         parent::__construct($this);
  16.     }
  17.  
  18.     function __call($name, $args) {
  19.         foreach ($this->getMethods() as $method)
  20.             if (strpos($method->getShortName(), $name) === 0 && $this->compare($method->getParameters(), $args))
  21.                 return call_user_func_array([$this, $method->getName()], $args);
  22.         throw new \ReflectionException;
  23.     }
  24.  
  25. }
  26.  
  27. class Test extends Overridable {
  28.  
  29.     protected function method0($integer) {
  30.         var_dump(__METHOD__, "Hola, has ingresado: '$integer'");
  31.     }
  32.  
  33.     protected function method1($string) {
  34.         var_dump(__METHOD__, "Hola, has ingresado: '$string'");
  35.     }
  36.  
  37.     protected function method2($integer, $string) {
  38.         var_dump(__METHOD__, "Hola, has ingresado: '$integer' y '$string'");
  39.     }
  40.  
  41.     protected function method3($string, $integer) {
  42.         var_dump(__METHOD__, "Hola, has ingresado: '$string' y '$integer'");
  43.     }
  44.  
  45. }
  46.  
  47. $test = new Test;
  48.  
  49. $test->method(1);
  50. $test->method('hola');
  51. $test->method(99, 'hola');
  52. $test->method('hola', 1);

Esto es un aporte a tu aporte, no existe ni mejor ni peor solución, sólo diferentes y me parecía excesivo abrir un tema cuando justo estábamos desarrollando algo parecido cada uno para sus diferentes fines.
  #3 (permalink)  
Antiguo 12/03/2014, 03:04
lolainas
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: APORTE: Emular polimorfismo y sobrecarga tipada de forma simple.

Me gustaría agregar, si no te importa, que el título del post puede confundir y mucho, una cosa es la sobrecarga de métodos y otra el polimorfismo, el polimorfismo basicamente es que un objeto puede adquirir muchas (poli) formas (morfi), un ejemplo básico de polimorfismo:
Código PHP:
Ver original
  1. <?php
  2.  
  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 Human {
  20.     function drive(Vehicle $vehicle) {
  21.         $vehicle->run();
  22.     }
  23. }
  24.  
  25. (new Human)->drive(new Car);
  26. (new Human)->drive(new Train);

Creo que cabe aclararlo. Saludos.

Última edición por lolainas; 12/03/2014 a las 07:07
  #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
  #5 (permalink)  
Antiguo 12/03/2014, 17:28
lolainas
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: APORTE: Emular polimorfismo y sobrecarga tipada de forma simple.

Me gusta!, aunque te has complicado un poco con el tema errores, en principio las clases no deben manejar errores, deben lanzar excepciones, precisamente por eso extiendo de ReflectionObject, captar los errores sería tan sencillo como usar un bloque try-catch y atrapar ReflectionException's, la clase en principio la he escrito pensando utilizarla mas o menos así:
Código PHP:
Ver original
  1. try {
  2.     $test = new Test;
  3.     $test->method(1);
  4.     $test->method('hola');
  5.     $test->method(99, 'hola');
  6.     $test->method('hola', 1);
  7. }
  8. catch (\ReflectionException $ex) {
  9.     echo $ex->getMessage();
  10.     //La aplicación sigue viva y sé lo que está pasando
  11.     //Está pasando que el metodo no existe...
  12.     //puedo actuar en consecuencia...
  13. }

Saludos.
  #6 (permalink)  
Antiguo 13/03/2014, 10:13
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.

El problema esta en el casting a tipos nativos que no esta soportado por php, es por eso que se incorpora el handler de errores, sin embargo este solo permite el paso de ese error de casting particular. por lo que el bloque try catch que tu propones, sigue siendo necesario.
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #7 (permalink)  
Antiguo 13/03/2014, 15:24
lolainas
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: APORTE: Emular polimorfismo y sobrecarga tipada de forma simple.

Si tuviese ese problema me pasaría a JSP o ASP (por ejemplo) y dejaría PHP para otra cosa...
  #8 (permalink)  
Antiguo 13/03/2014, 19:22
Avatar de hhs
hhs
Colaborador
 
Fecha de Ingreso: junio-2013
Ubicación: México
Mensajes: 2.995
Antigüedad: 10 años, 9 meses
Puntos: 379
Respuesta: APORTE: Emular polimorfismo y sobrecarga tipada de forma simple.

Creo que el titulo debio decir algo como "Simulación de Polimorfismo estatico en lenguajes no tipificados" .

El aporte como experimento o simulación es interesante, pero no usaría algo que no implementa el lenguaje como una característica inherente a el. El polimorfismo estático es común en lenguajes tipificados como java, php no lo es. Si quieres "sobrecarga de métodos" generalmente se hace usando parametros por default: http://www.php.net/manual/en/functions.arguments.php o con arreglos.

Cita:
El problema esta en el casting a tipos nativos que no esta soportado por php, es por eso que se incorpora el handler de errores, sin embargo este solo permite el paso de ese error de casting particular. por lo que el bloque try catch que tu propones, sigue siendo necesario.
El problema es que quieres usar un lenguaje como si fuera otro. Cada lenguaje tiene sus propias características, ventajas y desventajas. Simular características que no son del lenguaje, puede ser el primer paso al desastre.
Si quieres probar algo sobre control de tipos de datos en php puedes usar estas clases experimentales: http://www.php.net/manual/en/book.spl-types.php O esperar a que algunas de las siguientes propuestas se implementen en el lenguaje: https://wiki.php.net/rfc/typechecking.

En general puedes sobrevivir sin la sobrecarga de métodos, pero si tu problema realmente lo requiere de la forma que lo hace java, entonces tu lenguaje es otro.

Por ultimo creo que tu aporte no funcionaria del todo bien cuando usas otra clase que herede a Test. Fuera de eso es ingenioso el artificio.
__________________
Saludos
About me
Laraveles
A class should have only one reason to change.
  #9 (permalink)  
Antiguo 18/05/2014, 14:35
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.

Bueno, veo que hubo varias sugerencias y criticas constructivas sobre esto, asi que aqui publico la nueva version que contempla todo lo que se planteo, y ademas, esta optimizada en comparacion a la anterior, la van a encontrar bastante flexible, aqui esta:

Código PHP:
Ver original
  1. <?php
  2.  namespace NS;
  3.  
  4.  class OverridableType extends \ReflectionObject
  5.  {
  6.     private $overload = array();
  7.     private static $overloadStatic = array();
  8.  
  9.     public function __construct()
  10.     {
  11.         parent::__construct($this);
  12.  
  13.         foreach ($this->getMethods() as $method)
  14.         {
  15.             $info = array_filter(array_map(function($val)
  16.                                             {
  17.                                                 $filter = trim(trim($val, '/*'));
  18.                                                 return ($filter ? explode(" ", $filter) : null);
  19.                                             }, explode("\n", $method->getDocComment())));
  20.             if($info)
  21.             {
  22.                 $tmp = array("params" => array());
  23.                 foreach($info as $directive)
  24.                 {
  25.                     switch($directive[0])
  26.                     {
  27.                         case "@overload" : $tmp["method"]   = $directive[1]; break;
  28.                         case "@count"    : $tmp["count"]    = $directive[1]; break;
  29.                         case "@param"    : $tmp["params"][] = strtolower($directive[1]); break;
  30.                         case "@default"  : $tmp["default"]  = $directive[1]; break;
  31.                     }
  32.                 }
  33.  
  34.                 if($method->isStatic())
  35.                 {
  36.                     if($tmp["default"])
  37.                     {
  38.                         if($tmp["count"])
  39.                             self::$overloadStatic[get_called_class()][$tmp["method"]][$tmp["count"]]["default"] = $tmp["default"];
  40.                         else
  41.                            self::$overloadStatic[get_called_class()][$tmp["method"]]["default"] = $tmp["default"];
  42.                     } else
  43.                         self::$overloadStatic[get_called_class()][$tmp["method"]][$tmp["count"]][] = array("types" => $tmp["params"], "name" => $method->getShortName());
  44.                 } else {
  45.                     if($tmp["default"])
  46.                     {
  47.                         if($tmp["count"])
  48.                             $this->overload[$tmp["method"]][$tmp["count"]]["default"] = $tmp["default"];
  49.                         else
  50.                             $this->overload[$tmp["method"]]["default"] = $tmp["default"];
  51.                     }
  52.                     else
  53.                         $this->overload[$tmp["method"]][$tmp["count"]][] = array("types" => $tmp["params"], "name" => $method->getShortName());
  54.                 }
  55.             }
  56.         }
  57.     }
  58.  
  59.     private static function getNameOverload($name, $args, $map)
  60.     {
  61.         if(isset($map[$name]))
  62.         {
  63.             $cant = count($args);
  64.             if(isset($map[$name][$cant]))
  65.             {
  66.                 foreach($map[$name][$cant] as $nro => $method)
  67.                 {
  68.                     if($nro !== "default")
  69.                     {
  70.                         $match = true;
  71.                         foreach($method["types"] as $tnro => $type)
  72.                         {
  73.                             $argType = gettype($args[$tnro]);
  74.                             if(!($argType == $type) and !($argType == 'object' && ($args[$tnro] instanceof $type)))
  75.                             {
  76.                                 $match = false;
  77.                                 break;
  78.                             }
  79.                         }
  80.                         if($match)
  81.                             return $method["name"];
  82.                     }
  83.                 }                
  84.                 if(isset($map[$name][$cant]["default"]))
  85.                     return $map[$name][$cant]["default"];
  86.                 else
  87.                     die("No se pudo resolver el metodo $name con $cant argumentos tipados ".implode(", ",array_map(function($val) { return gettype($val); }, $args)).".");            
  88.             } elseif(isset($map["default"]))
  89.                 return $map["default"];
  90.             else
  91.                 die("No se pudo resolver el metodo $name con $cant argumentos.");
  92.         } else
  93.             die("No se pudo resolver el metodo $name.");
  94.     }
  95.  
  96.     function __call($name, $args)
  97.     {
  98.         return call_user_func_array([$this, self::getNameOverload($name, $args, $this->overload)], $args);
  99.     }
  100.  
  101.     function __callStatic($name, $args)
  102.     {
  103.         return forward_static_call([$this, self::getNameOverload($name, $args, self::$overloadStatic[get_called_class()])], $args);
  104.     }
  105.  }
  106.  
  107.  // Y asi es como se implementa.
  108.  interface Vehicle
  109.  {
  110.      function run();
  111.  }
  112.  
  113.  namespace NSA;
  114.  
  115.  class Train implements \NS\Vehicle {
  116.     function run() {
  117.         echo 'chu-chua, chu-chua, chu-chua, ...<br />';
  118.     }
  119.  }
  120.  
  121.  namespace NSB;
  122.  
  123.  class Train implements \NS\Vehicle {
  124.     function run() {
  125.         echo 'chu-chub, chu-chub, chu-chub, ...<br />';
  126.     }
  127.  }
  128.  
  129.  namespace NS;
  130.  
  131.  class Car implements Vehicle {
  132.      function run() {
  133.          echo 'run, run, run, run, ...<br />';
  134.      }
  135.  }
  136.  
  137.  class Moto implements Vehicle {
  138.      function run() {
  139.          echo 'rrrrrrrrrrrrrrrrrrrr ...<br />';
  140.      }
  141.  }
  142.  
  143.  class Foto {
  144.      function sepia() {
  145.          echo 'me volvi sepia...<br />';
  146.      }
  147.  }
  148.  
  149.  class Test extends OverridableType
  150.  {
  151.     /**
  152.       @overload miMetodo
  153.       @count 0
  154.     */
  155.     public static function smethod()
  156.     {
  157.          echo("<br>Hola, no has ingresado nada de forma estatica<br>");
  158.     }
  159.    
  160.     /**
  161.       @overload miMetodo
  162.       @count 1
  163.       @param integer
  164.     */
  165.     public static function smethod1()
  166.     {
  167.          echo("<br>Hola, has ingresado: $unNumero estaticamente<br>");
  168.     }
  169.  
  170.     /**
  171.       @overload miMetodo
  172.       @count 0
  173.     */
  174.     public function method()
  175.     {
  176.          echo("<br>Hola, no has ingresado nada<br>");
  177.     }
  178.  
  179.     /**
  180.       @overload miMetodo
  181.       @count 1
  182.       @param integer
  183.     */
  184.     public function method1($unNumero)
  185.     {
  186.          echo("<br>Hola, has ingresado: $unNumero<br>");
  187.     }
  188.  
  189.     /**
  190.       @overload miMetodo
  191.       @count 1
  192.       @param string
  193.     */
  194.     public function method2($miString)
  195.     {
  196.         echo("<br>Hola, has ingresado: '$miString'<br>");
  197.     }
  198.  
  199.     /**
  200.       @overload miMetodo
  201.       @count 1
  202.       @param Train
  203.     */
  204.     public function method3($unTren)
  205.     {
  206.         echo("<br>Hola, gracias por el tren<br>");
  207.         $unTren->run();
  208.     }
  209.    
  210.     /**
  211.       @overload miMetodo
  212.       @count 1
  213.       @param NSA\Train
  214.     */
  215.     public function method3a($unTren)
  216.     {
  217.         echo("<br>Hola, gracias por el tren del namespace a<br>");
  218.         $unTren->run();
  219.     }
  220.    
  221.     /**
  222.       @overload miMetodo
  223.       @count 1
  224.       @param NSB\Train
  225.     */
  226.     public function method3b($unTren)
  227.     {
  228.         echo("<br>Hola, gracias por el tren del namespace b<br>");
  229.         $unTren->run();
  230.     }
  231.  
  232.     /**
  233.       @overload miMetodo
  234.       @count 1
  235.       @param NS\Car
  236.     */
  237.     public function method4($unAuto)
  238.     {
  239.         echo("<br>Hola, gracias por el auto<br>");
  240.         $unAuto->run();
  241.     }
  242.  
  243.     /**
  244.       @overload miMetodo
  245.       @count 1
  246.       @param NS\Vehicle
  247.     */
  248.     public function method5($unVehiculo)
  249.     {
  250.         echo("<br>Hola, gracias por el vehiculo<br>");
  251.         $unVehiculo->run();
  252.     }
  253.  
  254.     /**
  255.       @overload miMetodo
  256.       @count 1
  257.       @param Object
  258.     */
  259.     public function method6($unObjeto)
  260.     {
  261.         echo("<br>Hola, me diste un objeto: ".get_class($unObjeto).", muchas gracias.<br>");
  262.     }
  263.  
  264.     /**
  265.       @overload miMetodo
  266.       @count 2
  267.       @param integer
  268.       @param string
  269.     */
  270.     public function method7($unNumero, $miString)
  271.     {
  272.          echo("<br>Hola, has ingresado un numero: $unNumero y un string '$miString'<br>");
  273.     }
  274.  
  275.     /**
  276.       @overload miMetodo
  277.       @count 2
  278.       @param string
  279.       @param integer
  280.     */
  281.     public function method8($miString, $unNumero)
  282.     {
  283.         echo("<br>Hola, has ingresado un string: '$miString' y un numero $unNumero<br>");
  284.     }
  285.    
  286.     /**
  287.       @overload miMetodo
  288.       @count 2
  289.       @param integer
  290.       @param integer
  291.     */
  292.     public function method9($unNumero, $otroNumero)
  293.     {
  294.         echo("<br>Hola, has ingresado un numero: $unNumero y un numero $otroNumero<br>");
  295.     }
  296.  }
  297.  
  298.  class Testb extends Test
  299.  {    
  300.     /**
  301.       @overload miMetodo
  302.       @count 2
  303.       @param string
  304.       @param integer
  305.     */
  306.     public function method8($miString, $unNumero)
  307.     {
  308.         echo("<br>Hola, has ingresado un string: '$miString' y un numero $unNumero pero en una subclase.<br>");
  309.     }
  310.  }
  311.  
  312.  $test = new Test;
  313.  
  314.  $test->miMetodo();
  315.  $test->miMetodo(1);
  316.  $test::miMetodo();
  317.  $test::miMetodo(1);
  318.  $test->miMetodo('hola');
  319.  $test->miMetodo(99, 'hola');
  320.  $test->miMetodo('hola', 1);
  321.  $test->miMetodo(1, 2);
  322.  $test->miMetodo(new Car);
  323.  $test->miMetodo(new \NSA\Train);
  324.  $test->miMetodo(new \NSB\Train);
  325.  $test->miMetodo(new Moto);
  326.  $test->miMetodo(new Foto);
  327.  
  328.  $testb = new Testb;
  329.  $testb->miMetodo('hola', 1);

produce esta salida:
Cita:

Hola, no has ingresado nada

Hola, has ingresado: 1

Hola, has ingresado: 'hola'

Hola, has ingresado un numero: 99 y un string 'hola'

Hola, has ingresado un string: 'hola' y un numero 1

Hola, has ingresado un numero: 1 y un numero 2

Hola, gracias por el auto
run, run, run, run, ...

Hola, gracias por el tren del namespace a
chu-chua, chu-chua, chu-chua, ...

Hola, gracias por el tren del namespace b
chu-chub, chu-chub, chu-chub, ...

Hola, gracias por el vehiculo
rrrrrrrrrrrrrrrrrrrr ...

Hola, me diste un objeto: NS\Foto, muchas gracias.

Hola, has ingresado un string: 'hola' y un numero 1 pero en una subclase.
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #10 (permalink)  
Antiguo 19/05/2014, 05:34
Avatar de dashtrash
Colaborador
 
Fecha de Ingreso: abril-2007
Ubicación: Ni en Sevilla,ni en Sanlúcar..qué más da..
Mensajes: 927
Antigüedad: 17 años
Puntos: 270
Respuesta: APORTE: Emular polimorfismo y sobrecarga tipada de forma simple.

Esta implementación está bastante mejor a nivel de funcionalidad.En los tests que incluyes creo que no hay gestión de parámetros opcionales, que creo que sí está intentando gestionar el código.
No soy un fan de meter código en los comentarios (aunque ese código no sea php), pero el código está más limpio que antes, y soporta más cosas.
  #11 (permalink)  
Antiguo 19/05/2014, 06:01
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años
Puntos: 292
Respuesta: APORTE: Emular polimorfismo y sobrecarga tipada de forma simple.

@NSD : se ve interesante pero genera muchos Warnings y Notices en PHP 5.4.26 :

Cita:

Warning: The magic method __callStatic() must have public visibility and be static in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 101

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 36

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 36

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Hola, no has ingresado nada

Hola, has ingresado: 1

Notice: Undefined variable: this in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 103

Warning: forward_static_call() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 103

Notice: Undefined variable: this in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 103

Warning: forward_static_call() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 103

Hola, has ingresado: 'hola'

Hola, has ingresado un numero: 99 y un string 'hola'

Hola, has ingresado un string: 'hola' y un numero 1

Hola, has ingresado un numero: 1 y un numero 2

Hola, gracias por el auto
run, run, run, run, ...

Hola, gracias por el tren del namespace a
chu-chua, chu-chua, chu-chua, ...

Hola, gracias por el tren del namespace b
chu-chub, chu-chub, chu-chub, ...

Hola, gracias por el vehiculo
rrrrrrrrrrrrrrrrrrrr ...

Hola, me diste un objeto: NS\Foto, muchas gracias.

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 36

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 36

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Notice: Undefined index: default in C:\WWW\apache2\htdocs\pruebas\polimorfismo con ReflectionObject.php on line 45

Hola, has ingresado un string: 'hola' y un numero 1 pero en una subclase.
__________________
Salu2!
  #12 (permalink)  
Antiguo 19/05/2014, 11:00
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.

Gracias Italico76 y dashtrash, cuando tenga unos ratos libres movere el codigo a github y vere de ampliarlo un poco mas y aplicar las sugerencias, intentare tambien evitar el uso de reflection, que a mi gusto personal es lo que no me convence para aplicar esta clase en un entorno real, ya que se esta pagando con rendimiento una caracteristica que no es del todo necesaria.

Luego pongo el link aqui, saludos.
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #13 (permalink)  
Antiguo 19/05/2014, 17:32
Avatar de hhs
hhs
Colaborador
 
Fecha de Ingreso: junio-2013
Ubicación: México
Mensajes: 2.995
Antigüedad: 10 años, 9 meses
Puntos: 379
Respuesta: APORTE: Emular polimorfismo y sobrecarga tipada de forma simple.

Antes de comentar, necesito saber algo NSD. Que es lo que soluciona tu aporte y como es que esperas que funcione en entornos reales ??

Cita:
Iniciado por NSD Ver Mensaje
Intentare tambien evitar el uso de reflection, que a mi gusto personal es lo que no me convence para aplicar esta clase en un entorno real, ya que se esta pagando con rendimiento una caracteristica que no es del todo necesaria.

Luego pongo el link aqui, saludos.
No es la reflexión, aun que prescindas de ella tu solución seguira limitada.
__________________
Saludos
About me
Laraveles
A class should have only one reason to change.
  #14 (permalink)  
Antiguo 20/05/2014, 15:04
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.

Cita:
Que es lo que soluciona tu aporte y como es que esperas que funcione en entornos reales ??
No soluciona nada, solo emula una característica que hace mas amigable el lenguaje de cara al programador, no pretende solucionar a ningun problema, como bien tu dijiste:
Cita:
En general puedes sobrevivir sin la sobrecarga de métodos, pero si tu problema realmente lo requiere de la forma que lo hace java, entonces tu lenguaje es otro.
Y la verdad, no pretendo que funcione en entornos reales, un cambio de este tipo deberia ser implementado en el nucleo de php, es decir en C, no con una clase php.
Si buscas en la web experimentos CSS3 encontraras muchas cosas interesantes pero de discutible aplicacion practica, sin embargo de php no hay tanta variedad, esto no es mas que eso, un pequeño experimento que puede servir con fines didacticos, o como una curiosidad, es responsabilidad de cada programador saber aplicarlo en un entorno real. Con saber que se puede, y que alguien lo hizo y que esta disponible para cuando lo necesites (si es que llega ese dia) es suficiente, no ambiciono a nada mas, ni siquiera a que alguien la use.
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #15 (permalink)  
Antiguo 20/05/2014, 18:10
Avatar de asus090102  
Fecha de Ingreso: mayo-2012
Ubicación: Ensenada- Buenos Aires
Mensajes: 67
Antigüedad: 11 años, 11 meses
Puntos: 1
Respuesta: APORTE: Emular polimorfismo y sobrecarga tipada de forma simple.

Uaaaauuuuuu, me siento como un mono tratando de entender porque le llama la atención que un rayo haya incendiado un árbol.
Sin ningún tipo de comprensión de que es el fuego en realidad, o el árbol, y el rayo obviamente menos que menos.
Creo que me voy a dedicar a estudiar papel mache, jajajajajaja.
  #16 (permalink)  
Antiguo 20/05/2014, 21:52
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.

Por si a alguien le interesa, dejo el link a github donde esta alojado esto y donde apareceran nuevas versiones, si existen. https://github.com/Proyecto-NSD/PHP-overload
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #17 (permalink)  
Antiguo 20/05/2014, 22:04
 
Fecha de Ingreso: febrero-2013
Mensajes: 78
Antigüedad: 11 años, 2 meses
Puntos: 0
Respuesta: APORTE: Emular polimorfismo y sobrecarga tipada de forma simple.

vaya , solo habia visto esto hace tiempo pero con java ..no sabia q tambien lo habia en PHP

Etiquetas: forma, sobrecarga
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 14:23.