|
|
Línea 593: |
Línea 593: |
| [[Archivo:salidaCall.png]] | | [[Archivo:salidaCall.png]] |
| }} | | }} |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− | ===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'''
| |
− | {{MMF_Definicion|Title=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.
| |
− | *Vamos a ver como podemos implementar la sobrecarga en php
| |
− | *Para simular la sobrecarga jugamos con el concepto de que una variable que no tenga valor se considera de tipo null
| |
− | *A coninuación una serie de ejemplos para dejar claro este concepto
| |
− | *Tomamos como ejemplo una función
| |
− | {{MRM_Ejemplo|
| |
− | <source lang=php>
| |
− | 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);
| |
− | }
| |
− | </source>
| |
− | }}<br />
| |
− |
| |
− | *Ahora la invocamos de diferente manera y vemos el resultado
| |
− | {{MRM_Ejemplo|Title=Invocar sin parámetros reales
| |
− | <source lang=php>
| |
− | echo "Invocando a <strong>verTipoParametros ()</strong><hr / />";
| |
− | verTipoParametros ();
| |
− | }
| |
− | </source>
| |
− |
| |
− | *A pesar de que tiene tres parámetros, la invacamos 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
| |
− | [[Imagen:funcionSinParametrosReales.png]]
| |
− | }}
| |
− |
| |
− | {{MRM_Ejemplo|Title=Invocar con 1 parámetro real
| |
− | <source lang=php>
| |
− | ...
| |
− | echo "Invocando a <strong>verTipoParametros (5)</strong><hr />";
| |
− | verTipoParametros (5);
| |
− | ...
| |
− | </source>
| |
− | *En esta caso invocamos con un solo parámetro de tipo entero
| |
− |
| |
− | *Podemos ver el resultado
| |
− | [[Imagen:funcion1ParametrosReal.png]]
| |
− | }}
| |
− |
| |
− |
| |
− | {{MRM_Ejemplo|Title=Invocar con 3 parámetros reales
| |
− | <source lang=php>
| |
− | ...
| |
− | echo "Invocando a <strong>verTipoParametros (5,7)</strong><hr />";
| |
− | verTipoParametros (5,7);
| |
− | ...
| |
− | </source>
| |
− | *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
| |
− | [[Imagen:funcion2ParametrosReal.png]]
| |
− | }}
| |
− | {{MRM_Ejemplo|Title=Invocar con 3 parámetro reales uno de ellos un array
| |
− | <source lang=php>
| |
− | ...
| |
− | echo "Invocando a <strong>verTipoParametros ([1,4,'maria'],true,'sonia')</strong><hr />";
| |
− | verTipoParametros ([1,4,'maria'],true,'sonia');
| |
− | ...
| |
− | </source>
| |
− | *Ahora igualemnte pasamos tres parámetros, pero uno de ellos es un array
| |
− | *Podemos ver el resultado
| |
− | [[Imagen:funcionParametroRealArray.png]]
| |
− | }}
| |
− |
| |
− |
| |
− | {{MRM_Ejemplo|Title=Invocar con 2 parámetro real
| |
− | <source lang=php>
| |
− | ...
| |
− | echo "Invocando a <strong>verTipoParametros ('pedro',5,9)</strong><hr />";
| |
− | verTipoParametros ('pedro',5,9);
| |
− | ...
| |
− | </source>
| |
− | *En esta caso invocamos con tres parámetros de diferente tipo
| |
− | {{Tipo|PHP lenguaje de tipado dinámico, vemos como el tipo puede cambiar en cada invocación}}
| |
− | *Ahora ya tenemos tres valores diferentes a null en los parámetros reales
| |
− | *Podemos ver el resultado
| |
− | [[Imagen:funcion3ParametrosReal.png]]
| |
− | }}
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− | *Supongamos que en el ejemplo anterior quisiérmos poder instanciar de la siguiente manera los racionales
| |
− | <source lang=php>
| |
− | $a = new racional ("8/5");/* 8/5 */
| |
− | $b = new racional (5,4); /* 5/6 */
| |
− | $c = new racional (5); /* 5/1 */
| |
− | $d = new racional (); /* 1/1 */
| |
− | </source>
| |
− | *Para esta situación tenemos diferentes estrategias. En este tema vamos a analizar 2:
| |
− | #sobrecargar en el constructor
| |
− | #sobrecargar con '''''métodos mágicos'''''
| |
− | ;Sobrecargar en el constructor
| |
− | *Una sencila es ir viendo de qué tipo son los parámetros
| |
− | *Vemos que podemos tener 0, 1 o 2 paŕametros
| |
− | *Por lo tanto la función constructora tendrá que tener 3 parámetros inicializados por si no le pasamos valores
| |
− | <source lang=php>
| |
− | public function __construct($cadenaOrNum=null, $den = null) {
| |
− | ....
| |
− | }
| |
− | </source>
| |
− | {{MRM_Actividad|Title=Sobrecargar el constructor de un racional|
| |
− | Siguiendo el ejemplo establecido anteriormente realiza un constructor que permita instanciar un objeto de la clase racional de la siguiente manera
| |
− | <source lang=php>
| |
− | $a = new racional ("8/5");/* 8/5 */
| |
− | $b = new racional (5,4); /* 5/6 */
| |
− | $c = new racional (5); /* 5/1 */
| |
− | $d = new racional (); /* 1/1 */
| |
− | </source>
| |
− | }}
| |
− | <!--
| |
− |
| |
− | Vamos a simular la sobre carga de la clase racional
| |
− |
| |
− | <source lang=php>
| |
− | <!--
| |
− | <?php
| |
− | /**
| |
− | * Description of racional
| |
− | *
| |
− | * @author manolo
| |
− | */
| |
− | class racional {
| |
− | //put your code here
| |
− | private $numRacional;
| |
− | private $num;
| |
− | private $den;
| |
− | public function __construct($cadenaOrNum=null, $den = null) {
| |
− | if (is_int($cadenaOrNum)){
| |
− | if (isset($den))
| |
− | $this->racionalNumDen($cadenaOrNum, $den );
| |
− | else
| |
− | $this->racionalNum($cadenaOrNum );
| |
− | }
| |
− | else{
| |
− | if (isset($cadenaOrNum))
| |
− | $this->racionalCadena($cadenaOrNum);
| |
− | else
| |
− | $this->racionalVacio();
| |
− | }
| |
− | }
| |
− |
| |
− | private function racionalNumDen($num, $den){
| |
− | $this->numRacional=$num."/".$den;
| |
− | $this->num=$num;
| |
− | $this->den=$den;
| |
− | $this->convierteNum();
| |
− | }
| |
− | private function racionalNum($num){
| |
− | $this->numRacional=$num."/1";
| |
− | $this->num=$num;
| |
− | $this->den=1;
| |
− | $this->convierteNum();
| |
− | }
| |
− | private function racionalCadena($cadenaOrNum){
| |
− | $this->numRacional=$cadenaOrNum;
| |
− | $pos = strpos($cadenaOrNum,"/");
| |
− |
| |
− | $num=substr($cadenaOrNum,0,$pos);
| |
− | $den=substr($cadenaOrNum,$pos+1);
| |
− | $this->num=$num;
| |
− | $this->den=$den;
| |
− | }
| |
− | private function racionalVacio(){
| |
− | $this->numRacional="1/1";
| |
− | $this->num=1;
| |
− | $this->den=1;
| |
− | }
| |
− | private function convierteNum(){
| |
− | settype($this->num, int);
| |
− | settype($this->den, int);
| |
− | }
| |
− |
| |
− |
| |
− |
| |
− | public function visualiza(){
| |
− | return $this->numRacional;
| |
− | }
| |
− | public function valorRacional(){
| |
− | return $this->num/$this->den;
| |
− | }
| |
− | private function simplifica(){
| |
− |
| |
− | }
| |
− | private function suma(racional $num){
| |
− |
| |
− | }
| |
− |
| |
− | }
| |
− |
| |
− | $a=new racional("8/5");
| |
− | $b=new racional("6/4");
| |
− | echo '<br>racional de $a: '. $a->visualiza();
| |
− | echo '<br>valor de $a: '. $a->valorRacional();
| |
− | echo '<br>racional de $b: '. $b->visualiza();
| |
− | echo '<br>valor de $b: '. $b->valorRacional();
| |
− | echo"<hr/>";
| |
− | $a=new racional();
| |
− | $b=new racional();
| |
− | echo '<br>racional de $a: '. $a->visualiza();
| |
− | echo '<br>valor de $a: '. $a->valorRacional();
| |
− | echo '<br>racional de $b: '. $b->visualiza();
| |
− | echo '<br>valor de $b: '. $b->valorRacional();
| |
− | echo"<hr/>";
| |
− | $a=new racional(8);
| |
− | $b=new racional(4);
| |
− | echo '<br>racional de $a: '. $a->visualiza();
| |
− | echo '<br>valor de $a: '. $a->valorRacional();
| |
− | echo '<br>racional de $b: '. $b->visualiza();
| |
− | echo '<br>valor de $b: '. $b->valorRacional();
| |
− | echo"<hr/>";
| |
− | $a=new racional(124,6);
| |
− | $b=new racional(7,123);
| |
− | echo '<br>racional de $a: '. $a->visualiza();
| |
− | echo '<br>valor de $a: '. $a->valorRacional();
| |
− | echo '<br>racional de $b: '. $b->visualiza();
| |
− | echo '<br>valor de $b: '. $b->valorRacional();
| |
− |
| |
− | ?>
| |
− |
| |
− | </source>
| |
− |
| |
− | }}
| |
− |
| |
− | *Código implementado en clase
| |
− | <!--
| |
− | <source lang=php>
| |
− | <?php
| |
− |
| |
− | /**
| |
− | * Description of racional
| |
− | *
| |
− | * @author alumno
| |
− | */
| |
− | class racional {
| |
− | //put your code here
| |
− | private $num;
| |
− | private $den;
| |
− | private $numRacional;
| |
− | public function __construct($cadenaOrNum=null, $den = null) {
| |
− | if (is_null($cadenaOrNum))
| |
− | $this->racionalVacio();
| |
− | else
| |
− | if (!(is_null($den)))
| |
− | $this->racionalNumDen($cadenaOrNum, $den );
| |
− | else
| |
− | if (is_int($cadenaOrNum))
| |
− | $this->racionalNum($cadenaOrNum);
| |
− | else
| |
− | $this->racionalCadena($cadenaOrNum);
| |
− | }
| |
− |
| |
− | //Sobrecargamos el método asigna de modo que se pueda implementar de las siguientes maneras
| |
− | /*asigna("6/4");
| |
− | asigna();
| |
− | asigna(8);
| |
− | asigna(124, 6);
| |
− | * */
| |
− |
| |
− | 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;
| |
− | }
| |
− |
| |
− |
| |
− |
| |
− |
| |
− | }
| |
− |
| |
− | }
| |
− | // caso $a = racional(8,7);
| |
− | private function racionalNumDen($num, $den ){
| |
− | $this->num=$num;
| |
− | $this->den=$den;
| |
− | $this->numRacional="$num/$den";
| |
− |
| |
− | }
| |
− | // caso $a = racional(8);
| |
− | private function racionalNum($num ){
| |
− | $this->num=$num;
| |
− | $this->den=1;
| |
− | $this->numRacional="$num/1";
| |
− |
| |
− | }
| |
− | // caso $a = racional("8/7");
| |
− | private function racionalCadena($cadena){
| |
− | $pos = strpos($cadena, "/");
| |
− | $num = substr($cadena,0, $pos);
| |
− | $den = substr($cadena ,$pos+1 );
| |
− |
| |
− | settype($num, "int");
| |
− | settype($den, "int");
| |
− |
| |
− | $this->num= $num;
| |
− | $this->den= $den;
| |
− | $this->numRacional=$cadena;
| |
− | }
| |
− | // caso $a = racional(); y se inicia con 1/1
| |
− | private function racionalVacio(){
| |
− | $this->num=1;
| |
− | $this->den=1;
| |
− | $this->numRacional="1/1";
| |
− |
| |
− |
| |
− | }
| |
− |
| |
− | public function visualiza(){
| |
− | echo "<br/>valor del numerador ".$this->num;
| |
− | echo "<br/>valor del denominador ".$this->den;
| |
− | echo "<br/>valor del racional ".$this->numRacional;
| |
− | echo "<br/>valor numerico ".($this->num/$this->den);
| |
− | }
| |
− | }
| |
− |
| |
− |
| |
− |
| |
− | //-------------------------
| |
− |
| |
− |
| |
− | $a= new racional();
| |
− | $b= new racional(5);
| |
− | $c= new racional(5,6);
| |
− | $d= new racional("6/6");
| |
− |
| |
− | $a->visualiza();
| |
− | $b->visualiza();
| |
− | $c->visualiza();
| |
− | $d->visualiza();
| |
− |
| |
− | $a->asigna(6000,545);
| |
− | $a->visualiza();
| |
− | $a->asigna("8458/55154");
| |
− | $a->visualiza();
| |
− | $a->asigna(85547);
| |
− | $a->visualiza();
| |
− | $a->asigna();
| |
− | $a->visualiza();
| |
− | ?>
| |
− |
| |
− |
| |
− |
| |
− | </source>
| |
− | -->
| |
− | ;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
| |
− | <source lang=php>
| |
− | // 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();
| |
− | </source>
| |
− | *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
| |
− | # $nombreFuncion es el nombre del método que se invoca
| |
− | # $argumentos es un array con los argumentos de la función
| |
− | {{MRM_Actividad| vamos a sobrecargar el método asigna() de la clase racional de modo que accepte sobrecarga
| |
− | }}
| |
− | <!--
| |
− | <source lang=php>
| |
− |
| |
− | $a=new racional();
| |
− |
| |
− | $a->asigna("6/4");
| |
− | echo '<br>racional de $a: '. $a->visualiza();
| |
− | echo '<br>valor de $a: '. $a->valorRacional();
| |
− |
| |
− | echo"<hr/>";
| |
− | $a->asigna();
| |
− | echo '<br>racional de $a: '. $a->visualiza();
| |
− | echo '<br>valor de $a: '. $a->valorRacional();
| |
− |
| |
− | echo"<hr/>";
| |
− | $a->asigna(8);
| |
− | echo '<br>racional de $a: '. $a->visualiza();
| |
− | echo '<br>valor de $a: '. $a->valorRacional();
| |
− |
| |
− | echo"<hr/>";
| |
− | $a->asigna(124, 6);
| |
− | echo '<br>racional de $a: '. $a->visualiza();
| |
− | echo '<br>valor de $a: '. $a->valorRacional();
| |
− | </source>
| |
− | <!--
| |
− | <source lang=php>
| |
− | <?php
| |
− |
| |
− | /*
| |
− | * To change this license header, choose License Headers in Project Properties.
| |
− | * To change this template file, choose Tools | Templates
| |
− | * and open the template in the editor.
| |
− | */
| |
− |
| |
− | /**
| |
− | * Description of racional
| |
− | *
| |
− | * @author manolo
| |
− | */
| |
− | class racional {
| |
− | //put your code here
| |
− | private $numRacional;
| |
− | private $num;
| |
− | private $den;
| |
− | public function __construct($argumento) {
| |
− |
| |
− | }
| |
− | public function __call($name, $argumentos) {
| |
− | if ($name=="asigna"){
| |
− | switch (count($argumentos)){
| |
− | case 0:
| |
− | $this->racionalVacio();
| |
− | break;
| |
− | case 1: //Aquí tenemos dos casos hay que ver el tipo
| |
− | if (is_int($argumentos[0]))
| |
− | $this->racionalNum($argumentos[0]);
| |
− | else
| |
− | $this->racionalCadena($argumentos[0]);
| |
− |
| |
− | break;
| |
− | case 2:
| |
− | $this->racionalNumDen($argumentos[0],$argumentos[1]);
| |
− | break;
| |
− | }
| |
− |
| |
− | }
| |
− |
| |
− | }
| |
− |
| |
− | private function racionalNumDen($num, $den){
| |
− | $this->numRacional=$num."/".$den;
| |
− | $this->num=$num;
| |
− | $this->den=$den;
| |
− | $this->convierteNum();
| |
− | }
| |
− | private function racionalNum($num){
| |
− | $this->numRacional=$num."/1";
| |
− | $this->num=$num;
| |
− | $this->den=1;
| |
− | $this->convierteNum();
| |
− | }
| |
− | private function racionalCadena($cadenaOrNum){
| |
− | $this->numRacional=$cadenaOrNum;
| |
− | $pos = strpos($cadenaOrNum,"/");
| |
− |
| |
− | $num=substr($cadenaOrNum,0,$pos);
| |
− | $den=substr($cadenaOrNum,$pos+1);
| |
− | $this->num=$num;
| |
− | $this->den=$den;
| |
− | }
| |
− | private function racionalVacio(){
| |
− | $this->numRacional="1/1";
| |
− | $this->num=1;
| |
− | $this->den=1;
| |
− | }
| |
− | private function convierteNum(){
| |
− | settype($this->num, int);
| |
− | settype($this->den, int);
| |
− | }
| |
− |
| |
− |
| |
− |
| |
− | public function visualiza(){
| |
− | return $this->numRacional;
| |
− | }
| |
− | public function valorRacional(){
| |
− | return $this->num/$this->den;
| |
− | }
| |
− | private function simplifica(){
| |
− |
| |
− | }
| |
− | private function suma(racional $num){
| |
− |
| |
− | }
| |
− |
| |
− | }
| |
− |
| |
− | $a=new racional();
| |
− | $b=new racional();
| |
− | $a->asigna("8/5");
| |
− | $b->asigna("6/4");
| |
− | echo '<br>racional de $a: '. $a->visualiza();
| |
− | echo '<br>valor de $a: '. $a->valorRacional();
| |
− | echo '<br>racional de $b: '. $b->visualiza();
| |
− | echo '<br>valor de $b: '. $b->valorRacional();
| |
− | echo"<hr/>";
| |
− | $a->asigna();
| |
− | $a->asigna();
| |
− | echo '<br>racional de $a: '. $a->visualiza();
| |
− | echo '<br>valor de $a: '. $a->valorRacional();
| |
− | echo '<br>racional de $b: '. $b->visualiza();
| |
− | echo '<br>valor de $b: '. $b->valorRacional();
| |
− | echo"<hr/>";
| |
− | $a->asigna(8);
| |
− | $b->asigna(4);
| |
− | echo '<br>racional de $a: '. $a->visualiza();
| |
− | echo '<br>valor de $a: '. $a->valorRacional();
| |
− | echo '<br>racional de $b: '. $b->visualiza();
| |
− | echo '<br>valor de $b: '. $b->valorRacional();
| |
− | echo"<hr/>";
| |
− | $a->asigna(124, 6);
| |
− | $b->asigna(124, 6);
| |
− | echo '<br>racional de $a: '. $a->visualiza();
| |
− | echo '<br>valor de $a: '. $a->valorRacional();
| |
− | echo '<br>racional de $b: '. $b->visualiza();
| |
− | echo '<br>valor de $b: '. $b->valorRacional();
| |
− |
| |
− | ?>
| |
− |
| |
− | </source>
| |
− | }}
| |
− | -->
| |
− | ==::==
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
| | | |
| | | |