sábado, 14 de julio de 2012

2.3.3 Sobrecarga de Métodos


Sobrecarga de métodos
El encabezado o firma de un método (la primera línea en el) nos dice que modificador tiene el método (publico, protegido, privado), su tipo de retorno (void o alguno de los tipos previamente vistos) y los parámetros que requiere para trabajar.
Pero ya que se define un método, éste puede definirse varias veces (sobrecargarse) en la misma clase, pero cambiando su encabezado de manera que sean otros los parámetros a utilizar, en C++ se pueden sobrecargar operadores, como el +, el - , etc., pero en Java no, en Java el operador + se puede utilizar para sumar números o para concatenar Strings solamente, la sobrecarga se puede realizar en métodos constructores o métodos no constructores.
Para ejemplificar la sobrecarga de métodos supongamos que tenemos alguna clase en la que se lleva el control del inventario de un artículo y puede ser que la cantidad que se reciba sea un entero, pero también pueda ser un número de doble precisión, o un objeto tipo String, entonces podemos tener el mismo método definido tres veces:
     public void cambia( int numero) {
        inventario = numero;
     }

     public void cambia( double numero) {
        // esto es la conversión de tipos usado también en C++
inventario = (int) numero;            
}

     public void cambia( String numero) {
// asumiendo que inventario es entero
        inventario = Integer.parseInt(numero);    
}
Cuando el método sea llamado, Java revisará cual es el método a utilizar dependiendo de la firma y el parámetro pasado.
Esto es muy utilizado también en los constructores de los objetos, por ejemplo pensemos en la clase Punto, en la que podemos construir un objeto Punto a partir de dos valores enteros, pero supongamos que también quisieran ser construidos a través de dos valores de precisión doble (double) o que se quisiera construir un objeto a partir de otro objeto Punto, veamos como quedaría la clase Punto:
public class Punto {
    private int x;  //  variable para la coordenada en x
    private int y; // variable para la coordenada en y
  
    // metodo para construir un objeto sin parámetros
public Punto() { 
          x = 0;
          y = 0;
    }

    // método para construir un objeto con parámetros enteros
public Punto(int x, int y) { 
          this.x = x;
          this.y = y;
    }

    // método para construir un objeto con parámetros double
public Punto(double x, double y) { 
          this.x = (int) x;
          this.y = (int) y;
    }

    // método para construir un objeto con parámetro objeto Punto
public Punto(Punto obj) { 
          this.x = obj.x;
          this.y = obj.y;
    }
  
    // método que te dá el valor de la coordenada x
public int obtenX() {        
          return x;
    }
    
    // método que te dá el valor de la coordenada y
public int obtenY() {        
          return y;
    }
   
    // método que sirve para cambiar el valor de la coordenada x
public void cambiaX(int x) { 
      // this se utiliza porque se esta utilizando (x) como parámetro y como
// variable de instancia y esto es para que no se confunda
this.x = x;                                        
    }

    // método que sirve para cambiar el valor de la coordenada y
public void cambiaY(int y) { 
      // this se utiliza porque se esta utilizando (y) como parámetro y como
// variable de instancia y esto es para que no se confunda
this.y = y;                                        
    }
}
En esta clase, ahora manejamos diferentes constructores para la clase, esto ya lo habíamos hecho antes, y es entonces que también los constructores se pueden definir de varias maneras. De la misma manera pudiéramos redefinir algún o algunos métodos.
Supongamos que los valores de x o de y, sean tomados no solamente de enteros sino de valores tipo double, entonces tendríamos una clase como la siguiente:
public class Punto {
    private int x;  //  variable para la coordenada en x
    private int y; // variable para la coordenada en y
  
    // metodo para construir un objeto sin parámetros
public Punto() { 
          x = 0;
          y = 0;
    }

    // método para construir un objeto con parámetros enteros
public Punto(int x, int y) { 
          this.x = x;
          this.y = y;
    }

    // método para construir un objeto con parámetros double
public Punto(double x, double y) { 
          this.x = (int) x;
          this.y = (int) y;
    }

    // método para construir un objeto con parámetro objeto Punto
public Punto(Punto obj) { 
          this.x = obj.x;
          this.y = obj.y;
    }
  
    // método que te dá el valor de la coordenada x
public int obtenX() {        
          return x;
    }
    
    // método que te dá el valor de la coordenada y
public int obtenY() {        
          return y;
    }
   
    // método que sirve para cambiar el valor de la coordenada x
public void cambiaX(int x) { 
      // this se utiliza porque se esta utilizando (x) como parámetro y como
// variable de instancia y esto es para que no se confunda
this.x = x;                                        
    }

    // método que toma un double para cambiar a x
public void cambiaX(double x) { 
      // this se utiliza porque se esta utilizando (x) como parámetro y como
// variable de instancia y esto es para que no se confunda
this.x = (int) x;                                        
    }

    // método que sirve para cambiar el valor de la coordenada y
public void cambiaY(int y) { 
      // this se utiliza porque se esta utilizando (y) como parámetro y como
// variable de instancia y esto es para que no se confunda
this.y = y;                                        
    }

    // método que toma un double para cambiar a y
public void cambiaY(double y) { 
      // this se utiliza porque se esta utilizando (y) como parámetro y como
// variable de instancia y esto es para que no se confunda
this.y = (int) y;                                        
    }

    // metodo para obtener el objeto en formato String
public String toString() { 
          return "(" + obtenX() + "," + obtenY() + ")";
    }
}

    
Una aplicación no gráfica que use esta clase para entender su manejo pudiera ser:
public class AplicacionPunto {
   private static Punto a, b, c, d, e;

   public static void main(String[] args) {
      a = new Punto();
      b = new Punto(1, 2);
      c = new Punto(3.0, 4.0);
      d = new Punto(b);
      e = new Punto(c);
      System.out.println(" Punto a = " + a.toString());
      System.out.println(" Punto b = " + b.toString());
      System.out.println(" Punto c = " + c.toString());
      System.out.println(" Punto d = " + d.toString());
      System.out.println(" Punto e = " + e.toString());
      a.cambiaX(5.0);
      c.cambiaY(-3.0);
      System.out.println("Valores cambiados");
      System.out.println(" Punto a = " + a.toString());
      System.out.println(" Punto c = " + c.toString());
   }
}

Ambas clases deben estar en la misma carpeta para que se pueda utilizar la aplicación
La forma en la que se puede visualizar esto es compilando como una aplicación no gráfica y ejecutándola, de la siguiente manera:

De esta manera observamos la manera de crear diferentes objetos de la clase Punto, y también observamos como es posible cambiar el valor de alguna de las variables de instancia de esos objetos utilizando un número de punto flotante en vez de un número entero.
Hemos hecho uso de una aplicación no gráfica para que se enfatice el uso de este concepto solamente.
Notarás que en la clase Punto utilizamos el método toString(), este método es muy utilizado en todas las clases Singulares, ya que es la manera de representar cualquier objeto de la clase en formato String.

No hay comentarios:

Publicar un comentario