domingo, 8 de noviembre de 2015

SOBRECARGA DE MÉTODOS EN JAVA (OVERLOADING)


Un método sobrecargado se utiliza para reutilizar el nombre de un método pero con diferentes argumentos (opcionalmente un tipo diferente de retorno). Las reglas para sobrecargar un método son las siguientes:

  • Los métodos sobrecargados debe de cambiar la lista de argumentos.
  • Pueden cambiar el tipo de retorno.
  • Pueden cambiar el modificador de acceso.
  • Pueden declarar nuevas o más amplias excepciones.
  • Un método puede ser sobrecargado en la misma clase o en una subclase.


Veamos un método que se desea sobrecargar:

public void cambiarTamano(int tamano, String nombre, float patron){ }

Los siguientes métodos son sobrecargas legales del método cambiarTamano():

public void cambiarTamano(int tamano, String nombre){}
public int cambiarTamano(int tamano, float patron){}
public void cambiarTamano(float patron, String nombre) throws IOException{}

Cómo invocar un método sobrecargado

Lo que define qué método es el que se va a llamar son los argumentos que se envían al mismo durante la llamada. Si se invoca a un método con un String como argumento, se ejecutará el método que tome un String como argumento, si se manda a llamar al mismo método pero con un float como argumento, se ejecutará el método que tome un float como argumento y así sucesivamente. Si se invoca a un método con un argumento que no es definido en ninguna de las versiones sobrecargadas entonces el compilador arrojará un mensaje de error.

Ejemplo de una clase con un método sobrecargado:

public class Sobrecarga {
public void Numeros(int x, int y){
System.out.println("Método que recibe enteros.");
}
public void Numeros(double x, double y){
System.out.println("Método que recibe flotantes.");
}
public void Numeros(String cadena){
System.out.println("Método que recibe una cadena: "+ cadena);
}
public static void main (String... args){
Sobrecarga s = new Sobrecarga();
int a = 1;
int b = 2;
s.Numeros(a,b);
s.Numeros(3.2,5.7);
s.Numeros("Monillo007");
}
}

Al ejecutar el código anterior obtendremos lo siguiente:

Método que recibe enteros.
Método que recibe flotantes.
Método que recibe una cadena

Al utilizar objetos en lugar de tipos primitivos o cadenas se vuelve más interesante. Veamos lo que sucede cuando se tiene un método sobrecargado que en una de sus versiones toma un Animal como parámetro y en otra un Caballo.

class Animal { }

class Caballo extends Animal{ }

class Animales{
public void MetodoSobrecargado(Animal a){
System.out.println("Método de parámetro Animal...");
}
public void MetodoSobrecargado(Caballo c){
System.out.println("Método de parámetro Caballo...");
}
public static void main(String... args){
Animales as = new Animales();
Animal objetoAnimal = new Animal();
Caballo objetoCaballo = new Caballo();
as.MetodoSobrecargado(objetoAnimal);
as.MetodoSobrecargado(objetoCaballo);
}
}

Al ejecutar el código anterior obtenemos:

Método de parámetro Animal...
Método de parámetro Caballo...

Como era de esperarse, cada objeto manda a llamar al método que le corresponde de acuerdo a su tipo, pero qué pasa si creamos una referencia Animal sobre un objeto Caballo...

Animal objetoAnimalRefCaballo = new Caballo();
as.MetodoSobrecargado(objetoAnimalRefCaballo);

El resultado es:

Método de parámetro Animal...

Aunque en tiempo de ejecución el objeto es un Caballo y no un Animal, la elección de qué método sobrecargado invocar no se realiza dinámicamente en tiempo de ejecución, el tipo de referencia, no el objeto actual, es el que determina qué método es el que se ejecutará.


Reglas de la sobrecarga y sobreescritura de métodos

Ahora que hemos visto ambas formas de reescribir métodos, revisemos las reglas y diferencias entre ambos tipos de reescritura:

  • Argumentos: En un método sobrecargado los argumentos deben de cambiar mientras que en un método sobreescrito NO deben cambiar.

  • El tipo de retorno: En un método sobrecargado el tipo de retorno puede cambiar, en un método sobreescrito NO puede cambiar, excepto por subtipos del tipo declarado originalmente.

  • Excepciones: En un método sobrecargado las excepciones pueden cambiar, en un método sobreescrito pueden reducirse o eliminarse pero NO deben de arrojarse excepciones nuevas o más amplias.

  • Acceso: En un método sobrecargado puede cambiar, en un método sobreescrito el acceso NO debe de hacerse más restrictivo(puede ser menos restrictivo).

  • Al invocar: En un método sobrecargado los argumentos son los que determinan qué método es el que se invocará, en un método sobreescrito el tipo de objeto determina qué método es elegido.


Esto es todo con la sobrecarga de métodos en Java. ¿Alguna duda? dejen sus comentario.

CONSTRUCTORES Y SOBRECARGA DE CONSTRUCTORES

Un constructor es un método especial de una clase que se llama automáticamente siempre que se declara un objeto de esa clase.

Su función es inicializar el objeto y sirve para asegurarnos que los objetos siempre contengan valores válidos.

Cuando se crea un objeto en Java se realizan las siguientes operaciones de forma automática:

1.  Se asigna memoria para el objeto.
2. Se inicializan los atributos de ese objeto con los valores predeterminados por el sistema.
3. Se llama al constructor de la clase que puede ser uno entre varios.

El constructor de una clase tiene las siguientes características:

Tiene el mismo nombre que la clase a la que pertenece.


En una clase puede haber varios constructores con el mismo nombre y distinto número de argumentos (se puede sobrecargar) para permitir inicializar un objeto con más o menos atributos.

Podríamos tener un constructor sin argumentos para crear un objeto con unos atributos por defecto y varios constructores con argumentos dependiendo de a qué atributos queramos dar valor.

Por ejemplo, para la clase Técnico:


public class Tecnico{
 public static final double SALARIO_BASE = 600;
 private String nombre;
 private int departamento;
 private float sueldo;

public Tecnico(){   //Constructor sin parámetros.
 nombre = "";
 departamento = 0;
 sueldo = SALARIO_BASE;
 }

public Tecnico(String nombre, int departamento, float sueldo){   //Constructor con todos los parámetros.
 this.nombre = nombre;
 this.departamento = departamento;
 this.sueldo = sueldo;
 }

public Tecnico(String nombre, float sueldo){   //Constructor con tres parámetros, que utiliza this().
 this(nombre, 0, sueldo);
 }

}


El primer constructor sin parámetros inicializa todos los atributos con valores por defecto para nombre, departamento y sueldo.

El segundo constructor tiene parámetros para cada atributo de Tecnico.
El tercer constructor tiene dos parámetros, nombre y sueldo. La referencia this se utiliza como forma de envío de llamada a otro constructor (siempre dentro de la misma clase), en este caso el segundo constructor.

Es decir en esta llamada:

Tecnico t3 = new Tecnico (“Jose Luis”, 1300.50f);
Estaremos invocando al constructor con tres parámetros así:  Tecnico(“Jose Luis”, 0, 1300.50f)

Los constructores no se heredan

Aunque las subclases heredan todos los métodos y variables de sus superclases, no heredan sus constructores.

Las clases sólo pueden obtener un constructor de dos formas: debe escribirlo el programador o, si éste no lo escribe, debe usar el constructor predeterminado. Siempre se llama al constructor del nivel superior además de llamar al constructor subordinado.

Llamada a constructores de nivel superior

Puede llamar a un determinado constructor de una superclase como parte de la inicialización de una subclase utilizando la palabra clave super en la primera línea del constructor de la subclase. Es preciso suministrar los argumentos adecuados a super().

Cuando no hay ninguna llamada a super con argumentos, se llama implícitamente al constructor de la superclase que tenga cero argumentos. Si en la superclase no hubiera un constructor sin argumentos se produciría un error de compilación.

La llamada super() puede adoptar cualquier cantidad de argumentos adecuados para los distintos constructores disponibles en la superclase, pero debe ser la primera sentencia del constructor.

Recordar:

  • Si se utilizan, es preciso que super o this sean la primera línea del constructor.
  • Si un constructor no contiene ninguna llamada a super(…) ni a this(…), el compilador introduce una llamada al constructor de la superclase sin argumentos.
  • Otros constructores pueden llamar también a super(…) o this(…), con lo que iríamos encadenando llamadas a constructores. Al final el constructor de la clase de nivel superior se ejecutará antes que ningún otro constructor subordinado.
  • Un constructor nunca puede tener ambas llamadas super(…) y this(…).

JUEGOS CON CLICK RATÓN! - VARIABLE CONTADOR

UTILIZACIÓN DE VARIABLE CONTADOR

En programación siempre nos será de gran ayuda una variable de tipo contador, la cual inicializara su valor en X por lo general en 0 y este se ira incrementando en +1 cada vez que se vuelva a ejecutar el código o alguna instrucción previamente escrita.

Scratch también nos permite realizar esto, veamos el siguiente ejemplo más didacticamente para ver su utilidad.
Nuestro amigo Gobo nos indicara que debemos pincharlo con el mouse para incrementar el Score y obtener así la máxima cantidad de puntos mientras juguemos.


Como se dieron cuenta cada vez que lográbamos alcanzar a pinchar a nuestro amigo, el Score iba incrementando en +1, manteniendo su resultado en el caso que si no se lograba pinchar a gobo.

Veamos el codigo en Scratch:


En scratch también esta la posibilidad de no solo iniciar un objeto pinchando la bandera verde, sino que también se puede realizar en este caso en particular al hacer clic en este objeto.

Se utilizo un ciclo por siempre para que se esconda y aparezca nuestro amigo, dando la instrucción números al azar haciéndolo estar en diferentes lados de la pantalla.

Para ver mas del proyecto realizado pincha acá

Espero les haya gustado, nos vemos hasta la siguiente publicación.

Agradecimientos:
- taller de jóvenes programadores
- profesor germán riveros por enseñarnos semana a semana.

Saludos
Erik!