Diferencia entre revisiones de «Plantilla:PHP/Sobrecarga»

De WikiEducator
Saltar a: navegación, buscar
 
(13 revisiones intermedias por el mismo usuario no mostrado)
Línea 1: Línea 1:
 
<div id=parrafo>
 
<div id=parrafo>
===Sobrecarga===
+
 
Un concepto muy importante y básico en la programación orientada a objetos.
+
=== Sobrecarga ===
La sobrecarga es una concreción del principio de '''polimorfismo'''
+
Es un concepto muy importante y básico en la programación orientada a objetos.
{{MRM_Definicion|Title=polimorfismo|
+
La sobrecarga es una concreción del principio de '''polimorfismo'''.
*Podemos tener varios métodos con el mimos nombre, pero diferente número de parámetros o con parámetros de diferente 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}}
+
{{MRM_Definicion|Title=Polimorfismo|
*Sin embargo este aspecto en php no es del todo intuitivo. No existe la sobrecarga como la entendemos en otros lenguajes.
+
* Podemos tener varios métodos con el mismo nombre, pero con diferente número de parámetros o con parámetros de distinto tipo
*No obstante tenemos técnicas para poder simular la sobrecarga.
+
* En 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.
*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.
+
* Sin embargo, este aspecto en PHP no es del todo intuitivo: no existe la sobrecarga como la entendemos en otros lenguajes.
*Tomamos como ejemplo una función:
+
* No obstante, disponemos de técnicas para poder ''simular'' la sobrecarga.
<div font=10px>
+
* En muchos casos resulta fundamental, especialmente al sobrecargar el '''constructor''' de una clase.
 +
* Para simular la sobrecarga en '''PHP''', aprovechamos que una variable que no tenga valor se considera del tipo '''null'''.
 +
* Lo veremos con una serie de ejemplos para dejar claro este concepto.
 +
 
 +
* Tomamos como ejemplo una función:
 +
 
 
{{MRM_Ejemplo|
 
{{MRM_Ejemplo|
 
<source lang=php>
 
<source lang=php>
function verTipoParametros($a=null,$b=null,$c=null){
+
function verTipoParametros($a = null, $b = null, $c = null){
     echo "Primer parámetro ";
+
     echo "Primer parámetro: ";
 
     var_dump($a);
 
     var_dump($a);
     echo "Segundo parámetro ";
+
     echo "Segundo parámetro: ";
 
     var_dump($b);
 
     var_dump($b);
     echo "Tercer parámetro ";
+
     echo "Tercer parámetro: ";
 
     var_dump($c);
 
     var_dump($c);
 
}
 
}
 
</source>
 
</source>
 
}}
 
}}
</div>
+
 
 
<br />
 
<br />
*Ahora la invocamos de diferente manera y vemos el resultado:
+
 
 +
* Ahora la invocamos de diferentes maneras y observamos el resultado:
 +
 
 
{{MRM_Ejemplo|Title=Invocar sin parámetros reales|
 
{{MRM_Ejemplo|Title=Invocar sin parámetros reales|
 
<source lang=php>
 
<source lang=php>
echo "Invocando a <strong>verTipoParametros ()</strong><hr / />";
+
echo "Invocando a <strong>verTipoParametros()</strong><hr />";
verTipoParametros ();
+
verTipoParametros();
}
+
 
</source>
 
</source>
  
 
+
* A pesar de que tiene tres parámetros, la invocamos sin argumentos. 
*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).
*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):
+
[[Archivo:funcionSinParametrosReales.png]]
[[Imagen:funcionSinParametrosReales.png]]
+
 
}}
 
}}
  
 
{{MRM_Ejemplo|Title=Invocar con 1 parámetro real|
 
{{MRM_Ejemplo|Title=Invocar con 1 parámetro real|
 
<source lang=php>
 
<source lang=php>
  ...
+
echo "Invocando a <strong>verTipoParametros(5)</strong><hr />";
  echo "Invocando a <strong>verTipoParametros (5)</strong><hr />";
+
verTipoParametros(5);
  verTipoParametros (5);
+
  ...
+
 
</source>
 
</source>
*En esta caso invocamos con un solo parámetro de tipo entero
+
* En este caso invocamos con un solo parámetro de tipo entero.
 
+
[[Archivo:funcion1ParametrosReal.png]]
*Podemos ver el resultado
+
[[Imagen:funcion1ParametrosReal.png]]
+
 
}}
 
}}
 
  
 
{{MRM_Ejemplo|Title=Invocar con 2 parámetros reales|
 
{{MRM_Ejemplo|Title=Invocar con 2 parámetros reales|
 
<source lang=php>
 
<source lang=php>
  ...
+
echo "Invocando a <strong>verTipoParametros(5,7)</strong><hr />";
echo "Invocando a <strong>verTipoParametros (5,7)</strong><hr />";
+
verTipoParametros(5,7);
verTipoParametros (5,7);
+
  ...
+
 
</source>
 
</source>
*En esta caso invocamos con dos parámetros de tipo entero
+
* En este 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
+
* Los parámetros dentro de la función serán tres: dos con valor entero y el tercero con valor y tipo '''null'''.
*Podemos ver el resultado
+
[[Archivo:funcion2ParametrosReal.png]]
[[Imagen:funcion2ParametrosReal.png]]
+
 
}}
 
}}
  
{{MRM_Ejemplo|Title=Invocar con 3 parámetro reales|
+
{{MRM_Ejemplo|Title=Invocar con 3 parámetros reales|
 
<source lang=php>
 
<source lang=php>
  ...
+
echo "Invocando a <strong>verTipoParametros('pedro',5,9)</strong><hr />";
echo "Invocando a <strong>verTipoParametros ('pedro',5,9)</strong><hr />";
+
verTipoParametros('pedro',5,9);
verTipoParametros ('pedro',5,9);
+
  ...
+
 
</source>
 
</source>
*Ahora  pasamos tres parámetros, como vemos el primero de tipo string y los otros dos enteros
+
* En este caso pasamos tres parámetros: el primero de tipo string y los otros dos de tipo entero.
*Podemos ver el resultado
+
[[Archivo:funcion3ParametrosReal.png]]
[[Imagen:funcion3ParametrosReal.png]]
+
 
}}
 
}}
  
 
+
{{MRM_Ejemplo|Title=Invocar con 3 parámetros reales, uno de ellos un '''array'''|
{{MRM_Ejemplo|Title=Invocar con 3 parámetro reales uno de ellos un '''array'''|
+
 
<source lang=php>
 
<source lang=php>
  ...
+
echo "Invocando a <strong>verTipoParametros([1,4,'maría'], true, 'sonia')</strong><hr />";
echo "Invocando a <strong>verTipoParametros ([1,4,'maría'],true,'sonia')</strong><hr />";
+
verTipoParametros([1,4,'maría'], true, 'sonia');
verTipoParametros ([1,4,'maría'],true,'sonia');
+
  ...
+
 
</source>
 
</source>
*Ahora igualmente pasamos tres parámetros, pero uno de ellos es un array
+
* Ahora igualmente pasamos tres parámetros, pero uno de ellos es un array.
*Podemos ver el resultado
+
[[Archivo:funcionParametroRealArray.png]]
[[Imagen:funcionParametroRealArray.png]]
+
 
}}
 
}}
  
 +
==== Sobrecargando el constructor ====
 +
* Usando esta forma de trabajar, vamos a ''sobrecargar'' el constructor de una clase. 
 +
* Tomemos como ejemplo una clase '''Racional'''. Un número racional es un objeto que tiene numerador y denominador.
 +
[[Archivo:claseRacional.png]]
  
====Sobrecargando el constructor====
+
* Queremos permitir crear el objeto de distintas formas:
*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
+
[[Imagen:claseRacional.png]]
+
*Ahora a la hora de construir el objeto planteamos la posibilidad de poder  instanciar de la siguiente manera:
+
 
<source lang=php>
 
<source lang=php>
$r1 = new Racional ("8/5");/*   8/5 */
+
$r1 = new Racional("8/5"); /* 8/5 */
$r2 = new Racional (5,4); /*   5/*/
+
$r2 = new Racional(5,4);   /* 5/4 */
$r3 = new Racional (5);   /*   5/1 */
+
$r3 = new Racional(5);     /* 5/1 */
$r4 = new Racional ();     /*   1/1   */
+
$r4 = new Racional();     /* 1/1 */
 
</source>
 
</source>
*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.
+
* Necesitamos que el constructor pueda responder a todas las situaciones
{{Tip|Recordar que null también es un tipo}}
+
* Aplicando los conceptos vistos, solo tenemos que comprobar '''de qué tipo''' son los parámetros.
*Vemos que podemos tener 0, 1 o 2 parámetros
+
{{Tip|Recordar que ''null'' también es un tipo.}}
*Por lo tanto la función constructora tendrá que tener 2 parámetros  
+
 
 +
* Vemos que podemos tener 0, 1 o 2 parámetros
 +
Por lo tanto, el constructor tendrá dos parámetros opcionales.
  
 
<source lang=php>
 
<source lang=php>
public function __construct($num=null, $den=null) {
+
public function __construct($num = 1, $den = 1) {
....
+
    ...
 
}
 
}
 
</source>
 
</source>
*Especificamos el código do cómo se podría hacer
+
 
 +
* Especificamos el código de cómo se podría implementar:
  
 
<source lang=php>
 
<source lang=php>
Línea 124: Línea 117:
 
     private $den;
 
     private $den;
  
     public function __construct($num=null, $den=null) {
+
     public function __construct($num = 1, $den = 1) {
         //opciones new Racional () =>1/1
+
         // opciones:
         //opciones new Racional (5) =>5/1
+
        // new Racional()       => 1/1
         //opciones new Racional ("5/2") =>5/2
+
         // new Racional(5)     => 5/1
         ////opciones new Racional (5,2) =>5/2
+
         // new Racional("5/2") => 5/2
         //Otra sitiación no se instancia
+
         // new Racional(5,2)   => 5/2
        if (is_null($den)) {
+
         // Otra situación: no se instancia correctamente
            switch (is_numeric($num)) {
+
                case true:
+
                    $this->racionalNum($num);
+
                    break;
+
                case false:
+
                    if (is_null($num)){
+
                        $this->racionalVacio();
+
                        break;
+
                    }
+
                    else {
+
                        $this->racionalCadena($num);
+
                        break;
+
                    }
+
            }
+
        }else {
+
            $this->racionalNumDen($num,$den);
+
        }
+
  
 +
        if (is_string($num)) {
 +
            $numero = explode("/", $num);
 +
            $num = $numero[0];
 +
            $den = $numero[1];
 +
        }
 +
        $this->num = $num;
 +
        $this->den = $den;
 +
    }
  
   
+
     /* Método para visualizar el objeto como cadena de caracteres */
     /*Método para visualizar el objeto como cadena de caracteres*/
+
 
     public function __toString() {
 
     public function __toString() {
         return ($this->num."/".$this->den);
+
         return ($this->num . "/" . $this->den);
 
     }
 
     }
  
     //A continuación los métodos privados para asignar valores
+
     // Métodos privados para asignar valores según la forma de invocación
 
     private function racionalNum($num) {
 
     private function racionalNum($num) {
 
         $this->num = $num;
 
         $this->num = $num;
 
         $this->den = 1;
 
         $this->den = 1;
 
     }
 
     }
 +
 
     /**
 
     /**
    *
+
     * @param string $num número racional del tipo "a/b"
     * @param string $num numero racional del tipo "a/b"
+
     * Hay muchas formas de poder descomponer esa cadena en dos números.
     * hay muchas forma de poder descomponer ese array en dos números
+
 
     */
 
     */
 
     public function racionalCadena($num) {
 
     public function racionalCadena($num) {
         $this->num = (int) $num;
+
        $partes = explode("/", $num);
         $this->den = substr($num, strpos($num, "/") + 1);
+
         $this->num = (int) $partes[0];
 +
         $this->den = (int) $partes[1];
 
     }
 
     }
 +
 
     public function racionalVacio() {
 
     public function racionalVacio() {
 
         $this->num = 1;
 
         $this->num = 1;
Línea 175: Línea 160:
 
     }
 
     }
  
     /*En este caso si los valores son incorrectos asigno el racional 1/1 */
+
     /* En este caso, si los valores son incorrectos, asigno el racional 1/1 */
 
     public function racionalNumDen($num, $den) {
 
     public function racionalNumDen($num, $den) {
         if (is_numeric ($num) && is_numeric($den)){
+
         if (is_numeric($num) && is_numeric($den)) {
 
             $this->num = $num;
 
             $this->num = $num;
 
             $this->den = $den;
 
             $this->den = $den;
         }else{
+
         } else {
 
             $this->num = 1;
 
             $this->num = 1;
 
             $this->den = 1;
 
             $this->den = 1;
 
         }
 
         }
 
     }
 
     }
}
+
}
 
</source>
 
</source>
*Probamos este constructor con el siguiente código
+
 
 +
;Esta sería una posibilidad, pero podemos crear un código más compacto. 
 +
En la siguiente versión inicializamos los parámetros con un valor por defecto (<span class="r">1</span>). 
 +
Posteriormente, si el primer parámetro es una cadena, se divide en numerador y denominador. 
 +
Hecho esto, solo queda asignar los valores a los atributos.
 +
 
 
<source lang=php>
 
<source lang=php>
$a= new Racional();
+
public function __construct($num = 1, $den = 1){
$b= new Racional(5);
+
    if (is_string($num)){
$c= new Racional(5,6);
+
        $numero = explode("/", $num);
$d= new Racional("6/6");
+
        $num = $numero[0];
 +
        $den = $numero[1];
 +
    }
 +
    $this->num = $num;
 +
    $this->den = $den;
 +
}
 +
</source>
  
echo "Valor del racional \$a = $a <br />";
+
* Probamos este constructor con el siguiente código:
echo "Valor del racional \$b = $b <br />";
+
 
echo "Valor del racional \$c = $c <br />";
+
<source lang=php>
echo "Valor del racional \$d = $d <br />";
+
$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 />";
 
</source>
 
</source>
*Mostrando los siguientes resultados
 
Valor del racional $a <nowiki>=</nowiki> 1/1
 
Valor del racional $b <nowiki>=</nowiki> 5/1
 
Valor del racional $c <nowiki>=</nowiki> 5/6
 
Valor del racional $d <nowiki>=</nowiki> 6/6
 
  
====Sobrecarga con __call(...)====
+
* Mostrando los siguientes resultados:
*Otra forma de poder hacer lo mismo es usando el método mágico __call($funcion, $parametros).
+
 
{{Tip|El método mágico __call(..) es ejecutado cuando invocamos a un método que no existe en la clase}}
+
Valor del racional $a <nowiki>=</nowiki> 1/1 
 +
Valor del racional $b <nowiki>=</nowiki> 5/1 
 +
Valor del racional $c <nowiki>=</nowiki> 5/6 
 +
Valor del racional $d <nowiki>=</nowiki> 6/6 
 +
 
 +
==== Sobrecarga con __call(...) ====
 +
* Otra forma de lograr un comportamiento similar es usando el método mágico '''__call($funcion, $parametros)'''.
 +
{{Tip|El método mágico __call(...) se ejecuta cuando invocamos un método que no existe en la clase.}}
 +
 
 +
* Queremos usar un método llamado '''asigna()''' que nos permita cambiar el valor de un racional. 
 +
* La forma de aportar el nuevo valor será la misma que la de construir el objeto.
  
*Ahora queremos usar un método llamado '''''asigna''''' que nos permita cambiar el valor de un racional. La forma de aportar el nuevo valor, queremos que sea la misma que la forma de construir el objeto
 
 
<source lang=php>
 
<source lang=php>
$r1 = new Racional (); //construye el objeto 1/1
+
$r1 = new Racional();     // construye el objeto 1/1
+
$r1->asigna("6/4");       // ahora el objeto vale 6/4
$r1->asigna("6/4"); //Ahora el objeto vale 6/4
+
$r1->asigna();             // ahora el objeto vale 1/1
$r1->asigna(); //Ahora el objeto vale 1/1
+
$r1->asigna(8);           // ahora el objeto vale 8/1
$r1->asigna(8);//Ahora el objeto vale 8/1
+
$r1->asigna(124, 6);       // ahora el objeto vale 124/6
$r1->asigna(124, 6);//Ahora el objeto vale 124/6
+
</source>
</source>    
+
 
*La forma de proceder será usando los métodos privados creados anteriormente  
+
* La forma de proceder será usando los métodos privados creados anteriormente
*El siguiente código implementa la solución
+
* El siguiente código implementa la solución:
 +
 
 
<source lang=php>
 
<source lang=php>
 
public function __call($metodo, $argumentos) {
 
public function __call($metodo, $argumentos) {
        if ($metodo == "asigna"){
+
    if ($metodo == "asigna") {
            switch (count($argumentos)){
+
        switch (count($argumentos)) {
                case 0:
+
            case 0:
                    $this->racionalVacio();
+
                $this->racionalVacio();
                    break;
+
                break;
                case 2:
+
            case 2:
                    $this->racionalNumDen($argumentos[0], $argumentos[1]);
+
                $this->racionalNumDen($argumentos[0], $argumentos[1]);
                    break;
+
                break;
                case 1:
+
            case 1:
                    if (is_int($argumentos[0]))
+
                if (is_int($argumentos[0])) {
                        $this->racionalNum($argumentos[0]);
+
                    $this->racionalNum($argumentos[0]);
                    else
+
                } else {
                        $this->racionalCadena($argumentos[0]);
+
                    $this->racionalCadena($argumentos[0]);
                    break;
+
                }
            }
+
                break;
 
         }
 
         }
 
     }
 
     }
 +
}
 
</source>
 
</source>
 +
 
</div>
 
</div>

Última revisión de 05:47 7 nov 2025

Sobrecarga

Es 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 mismo nombre, pero con diferente número de parámetros o con parámetros de distinto tipo.
  • En 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, disponemos de técnicas para poder simular la sobrecarga.
  • En muchos casos resulta fundamental, especialmente al sobrecargar el constructor de una clase.
  • Para simular la sobrecarga en PHP, aprovechamos que una variable que no tenga valor se considera del tipo null.
  • Lo veremos con una serie de ejemplos para dejar claro este concepto.
  • Tomamos como ejemplo una función:



Icon casestudy.gif
Ejemplo
function verTipoParametros($a = null, $b = null, $c = null){
    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 diferentes maneras y observamos 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 argumentos.
  • 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 este caso invocamos con un solo parámetro de tipo entero.

Funcion1ParametrosReal.png




Icon casestudy.gif
Invocar con 2 parámetros reales
echo "Invocando a <strong>verTipoParametros(5,7)</strong><hr />";
verTipoParametros(5,7);
  • En este caso invocamos con dos parámetros de tipo entero.
  • Los parámetros dentro de la función serán tres: dos con valor entero y el tercero con valor y tipo null.

Funcion2ParametrosReal.png




Icon casestudy.gif
Invocar con 3 parámetros reales
echo "Invocando a <strong>verTipoParametros('pedro',5,9)</strong><hr />";
verTipoParametros('pedro',5,9);
  • En este caso pasamos tres parámetros: el primero de tipo string y los otros dos de tipo entero.

Funcion3ParametrosReal.png




Icon casestudy.gif
Invocar con 3 parámetros 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 igualmente pasamos tres parámetros, pero uno de ellos es un array.

FuncionParametroRealArray.png



Sobrecargando el constructor

  • Usando esta forma de trabajar, vamos a sobrecargar el constructor de una clase.
  • Tomemos como ejemplo una clase Racional. Un número racional es un objeto que tiene numerador y denominador.

ClaseRacional.png

  • Queremos permitir crear el objeto de distintas formas:
$r1 = new Racional("8/5"); /* 8/5 */
$r2 = new Racional(5,4);   /* 5/4 */
$r3 = new Racional(5);     /* 5/1 */
$r4 = new Racional();      /* 1/1 */
  • Necesitamos que el constructor pueda responder a todas las situaciones.
  • Aplicando los conceptos vistos, solo tenemos que comprobar 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, el constructor tendrá dos parámetros opcionales.

public function __construct($num = 1, $den = 1) {
    ...
}
  • Especificamos el código de cómo se podría implementar:
class Racional {
 
    private $num;
    private $den;
 
    public function __construct($num = 1, $den = 1) {
        // opciones:
        // new Racional()       => 1/1
        // new Racional(5)      => 5/1
        // new Racional("5/2")  => 5/2
        // new Racional(5,2)    => 5/2
        // Otra situación: no se instancia correctamente
 
        if (is_string($num)) {
            $numero = explode("/", $num);
            $num = $numero[0];
            $den = $numero[1];
        }
        $this->num = $num; 
        $this->den = $den;
    }
 
    /* Método para visualizar el objeto como cadena de caracteres */
    public function __toString() {
        return ($this->num . "/" . $this->den);
    }
 
    // Métodos privados para asignar valores según la forma de invocación
    private function racionalNum($num) {
        $this->num = $num;
        $this->den = 1;
    }
 
    /**
     * @param string $num número racional del tipo "a/b"
     * Hay muchas formas de poder descomponer esa cadena en dos números.
     */
    public function racionalCadena($num) {
        $partes = explode("/", $num);
        $this->num = (int) $partes[0];
        $this->den = (int) $partes[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;
        }
    }
}
Esta sería una posibilidad, pero podemos crear un código más compacto.

En la siguiente versión inicializamos los parámetros con un valor por defecto (1). Posteriormente, si el primer parámetro es una cadena, se divide en numerador y denominador. Hecho esto, solo queda asignar los valores a los atributos.

public function __construct($num = 1, $den = 1){
    if (is_string($num)){
        $numero = explode("/", $num);
        $num = $numero[0];
        $den = $numero[1];
    }
    $this->num = $num;
    $this->den = $den;
}
  • 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  

Sobrecarga con __call(...)

  • Otra forma de lograr un comportamiento similar es usando el método mágico __call($funcion, $parametros).
Icon present.gif
Tip: El método mágico __call(...) se ejecuta cuando invocamos un método que no existe en la clase.


  • Queremos usar un método llamado asigna() que nos permita cambiar el valor de un racional.
  • La forma de aportar el nuevo valor será la misma que la de construir el objeto.
$r1 = new Racional();      // construye el objeto 1/1
$r1->asigna("6/4");        // ahora el objeto vale 6/4
$r1->asigna();             // ahora el objeto vale 1/1
$r1->asigna(8);            // ahora el objeto vale 8/1
$r1->asigna(124, 6);       // ahora el objeto vale 124/6
  • La forma de proceder será usando los métodos privados creados anteriormente.
  • El siguiente código implementa la solución:
public function __call($metodo, $argumentos) {
    if ($metodo == "asigna") {
        switch (count($argumentos)) {
            case 0:
                $this->racionalVacio();
                break;
            case 2:
                $this->racionalNumDen($argumentos[0], $argumentos[1]);
                break;
            case 1:
                if (is_int($argumentos[0])) {
                    $this->racionalNum($argumentos[0]);
                } else {
                    $this->racionalCadena($argumentos[0]);
                }
                break;
        }
    }
}