Plantilla:PHP/Sobrecarga

De WikiEducator
Saltar a: navegación, buscar
Road Works.svg Trabajo en proceso, espera cambios frecuentes. Tu ayuda y retroalimentación son bienvenidos.
Ver página de charlas.
Road Works.svg


Sobrecarga

Un concepto muy importante y básico en la programación orientada a objetos.

La sobrecarga es una concreción del principio de polimorfismo


Icon define.gif
polimorfismo
  • Podemos tener varios métodos con el mimos nombre, pero diferente número de parámetros o con parámetros de difernte tipo
  • El tiempo de ejecución se ejecutará uno u otro en función de los parámetros reales que pasemos en la invocación del método


  • Sin embargo este aspecto en php no es del todo intuitivo. No existe la sobrecarga como la entendemos en otros lenguajes.
  • No obstante tenemos técnicas para poder simular la sobrecarga.
  • Muchas veces es fundamental. Especialmente importante a la hora de sobrecargar el constructor de la clase.
  • Para simular la sobrecarga en php, jugamos con el concepto de que una variable que no tenga valor se considera de tipo null.
  • Lo vemos con una serie de ejemplos para dejar claro este concepto.
  • Tomamos como ejemplo una función:


Icon casestudy.gif
Ejemplo
function verTipoParametros($a,$b,$c){
    echo "Primer parámetro ";
    var_dump($a);
    echo "Segundo parámetro ";
    var_dump($b);
    echo "Tercer parámetro ";
    var_dump($c);
}



  • Ahora la invocamos de diferente manera y vemos el resultado:


Icon casestudy.gif
Invocar sin parámetros reales
echo "Invocando a <strong>verTipoParametros ()</strong><hr / />";
verTipoParametros ();
}


  • A pesar de que tiene tres parámetros, la invocamos sin parámetros
  • El resultado será que cada parámetro al ejecutar la función será de tipo null con valor null (es un tipo válido en php):

FuncionSinParametrosReales.png




Icon casestudy.gif
Invocar con 1 parámetro real
  ... 
  echo "Invocando a <strong>verTipoParametros (5)</strong><hr />";
  verTipoParametros (5);
  ...
  • En esta caso invocamos con un solo parámetro de tipo entero
  • Podemos ver el resultado

Funcion1ParametrosReal.png





Icon casestudy.gif
Invocar con 2 parámetros reales
  ... 
echo "Invocando a <strong>verTipoParametros (5,7)</strong><hr />";
verTipoParametros (5,7);
  ...
  • En esta caso invocamos con dos parámetros de tipo entero
  • Al igual que en caso anterior los parámetros en la función serían 3, dos de ellos con valor de tipo entero, y el tercero con valor y tipo null
  • Podemos ver el resultado

Funcion2ParametrosReal.png




Icon casestudy.gif
Invocar con 3 parámetro reales
  ... 
echo "Invocando a <strong>verTipoParametros ('pedro',5,9)</strong><hr />";
verTipoParametros ('pedro',5,9);
  ...
  • Ahora pasamos tres parámetros, como vemos el primero de tipo string y los otros dos enteros
  • Podemos ver el resultado

Funcion3ParametrosReal.png





Icon casestudy.gif
Invocar con 3 parámetro reales uno de ellos un array
  ... 
echo "Invocando a <strong>verTipoParametros ([1,4,'maría'],true,'sonia')</strong><hr />";
verTipoParametros ([1,4,'maría'],true,'sonia');
  ...
  • Ahora igualemente pasamos tres parámetros, pero uno de ellos es un array
  • Podemos ver el resultado

FuncionParametroRealArray.png



Sobrecargando el constructor

  • Usando esta forma de trabajar vamos a sobre cargar el constructor de una clase
  • Tomamos una clase de tipo Racional. Un número Racional es un objeto que tendrá numerador y denominador

ClaseRacional.png

  • Ahora a la hora de construir el objeto planteamos la posibilidad de poderñp instanciar de la siguiente manera:
$r1 = new Racional ("8/5");/*   8/5  */
$r2 = new Racional (5,4);  /*   5/6  */
$r3 = new Racional (5);    /*   5/1  */
$r4 = new Racional ();     /*   1/1   */
  • Aquí vemos claramente que necesitamos sobrecargar el constructor para que pueda responder a todas las situaciones
  • Aplicando los conceptos vistos antes, lo único que tenemos que hacer en el constructor es ir viendo de qué tipo' son los parámetros.
Icon present.gif
Tip: Recordar que null también es un tipo


  • Vemos que podemos tener 0, 1 o 2 parámetros
  • Por lo tanto la función constructora tendrá que tener 2 parámetros
 public function __construct($num, $den) {
 ....
}
  • Especificamos el código do cómo se podría hacer
class Racional {
 
    private $num;
    private $den;
 
    public function __construct($num, $den) {
        //opciones new Racional () =>1/1
        //opciones new Racional (5) =>5/1
        //opciones new Racional ("5/2") =>5/2
        ////opciones new Racional (5,2) =>5/2
        //Otra sitiación no se instancia
        if (is_null($den)) {
            switch (is_numeric($num)) {
                case true:
                    $this->asigna(racionalNum($num);
                    break;
                case false:
                    if (is_null($num)){
                        $this->racionalVacio();
                        break;
                    }
                     else {
                        $this->racionalCadena($num);
                        break;
                     }
            }
        }else {
            $this->racionalNumDen($num,$den);
        }
 
 
 
    /*Método para visualizar el objeto como cadena de caracteres*/
    public function __toString() {
        return ($this->num."/".$this->den);
    }
 
    //A continuación los métodos privados para asignar valores
    private function racionalNum($num) {
        $this->num = $num;
        $this->den = 1;
    }
    /**
     * 
     * @param string $num numero racional del tipo "a/b"
     * hay muchas forma de poder descomponer ese array en dos números
     */
    public function racionalCadena($num) {
        $this->num = (int) $num;
        $this->den = substr($num, strpos($num, "/") + 1);
    }
    public function racionalVacio() {
        $this->num = 1;
        $this->den = 1;
    }
 
    /*En este caso si los valores son incorrectos asigno el racional 1/1  */
    public function racionalNumDen($num, $den) {
        if (is_numeric ($num) && is_numeric($den)){
            $this->num = $num;
            $this->den = $den;
        }else{
            $this->num = 1;
            $this->den = 1;
        }
    }
 }
  • Probamos este constructor con el siguiente código
$a= new Racional();
$b= new Racional(5);
$c= new Racional(5,6);
$d= new Racional("6/6");
 
echo "Valor del racional \$a  = $a <br />";
echo "Valor del racional \$b  = $b <br />";
echo "Valor del racional \$c  = $c <br />";
echo "Valor del racional \$d  = $d <br />";
  • Mostrando los siguientes resultados
Valor del racional $a = 1/1 
Valor del racional $b = 5/1 
Valor del racional $c = 5/6 
Valor del racional $d = 6/6 

}}

  • Código implementado en clase
métodos mágicos y la sobrecarga
  • Hemos visto __construct y __destruct
  • Vamos a analizar un método mágico para implementar la sobrecarga y exponer su funcionamiento
  • Ël método __call($nombreFuncion, $argumentos)' es un método mágico que se invoca cuando intentamos acceder a un método de la clase y este método no existe
  • Volvamos a nuestro racional
  • Supongamos que los métodos de sobrecarga que queremos son los usados en el constructor __construct
// caso $a = racional(8,7);
racionalNumDen($cadenaOrNum, $den );
// caso $a = racional(8);
racionalNum($cadenaOrNum );
// caso $a = racional("8/7");
racionalCadena($cadenaOrNum);
// caso $a = racional(); y se inicia con 1/1
racionalVacio();
  • Pero imagenimos que nos gustaría que todos tuvieran el mismo nombre, por ejemplo crea().
  • Vamos a usar el método __call para ello
  • Este método recibe dos argumentos
  1. $nombreFuncion es el nombre del método que se invoca
  2. $argumentos es un array con los argumentos de la función


Icon activity.jpg
Actividad
vamos a sobrecargar el método asigna() de la clase racional de modo que accepte sobrecarga




::