¿Para qué sirve la sobrecarga en Java?
En Java, dos o más métodos de una misma clase pueden tener el mismo nombre, siempre que sus declaraciones de parámetros sean diferentes. En este caso, el método se llama sobrecargado y el proceso se llama sobrecarga de métodos. La sobrecarga de métodos es una forma de implementar polimorfismo en Java. Si nunca antes ha utilizado un lenguaje que permita la sobrecarga de métodos, el concepto puede resultar un poco extraño al principio. Pero como verá, la sobrecarga de métodos es una de las características más interesantes y útiles de Java.
Cuando se llama a un método sobrecargado, Java usa el tipo y/o número de parámetros para indicar la versión del método sobrecargado que realmente se llama. Por tanto, el tipo y/o número de parámetros de cada método sobrecargado debe ser diferente. Aunque cada método sobrecargado puede tener un tipo de retorno diferente, el tipo de retorno no es suficiente para distinguir qué método se utiliza. Cuando Java llama a un método sobrecargado, se ejecuta el método cuyos parámetros coinciden con los parámetros de llamada.
El siguiente es un ejemplo sencillo para ilustrar la sobrecarga de métodos:
// Demuestra la sobrecarga de métodos.
class OverloadDemo {
void test () {
System.out.println("Sin parámetros");
}
// Prueba de sobrecarga para un parámetro entero
void test(int a) {
System.out.println("a: " a);
}
// Prueba de sobrecarga para dos parámetros enteros. void test(int a, int b) { System.out.println("a y b: " a " " b }
// prueba de sobrecarga para un parámetro doble p>
doble prueba(doble a) {
System.out.println("doble a: " a);
return a*a; >
class Overload {
public static void main(String args[]) {
OverloadDemo ob = new OverloadDemo();
doble resultado;
// llamar a todas las versiones de test()ob.test(); ob.test(10); ob.test(10, 20); resultado = ob.test(123.25); .println("Resultado de ob.test(123.25): " resultado);
}
}
El programa produce el siguiente resultado:
Sin parámetros
a: 10
a y b: 10 20
doble a: 123,25
Resultado de ob
Como se puede ver en el programa anterior, test() se ha sobrecargado cuatro veces. La primera versión no tiene parámetros, la segunda versión tiene un parámetro entero, la tercera versión tiene dos parámetros enteros y la cuarta versión tiene un parámetro doble. Dado que la sobrecarga no se ve afectada por el tipo de retorno del método, la cuarta versión de test() también devuelve un valor que no tiene relación causal con la sobrecarga.
Cuando se llama a un método sobrecargado, Java busca una coincidencia entre los parámetros del método que llama y los argumentos del método. Sin embargo, esta coincidencia no siempre es exacta. En algunos casos, la conversión automática de tipos de Java también funciona para argumentos de métodos sobrecargados.
Por ejemplo, considere el siguiente programa:
// Las conversiones de tipo automáticas se aplican a la sobrecarga.
class OverloadDemo {
void test() {
System.out.println("Sin parámetros");
}
// Prueba de sobrecarga para dos parámetros enteros void test(int a, int b) { System. out.println("a y b: " a " " b);}
// prueba de sobrecarga para un parámetro doble
prueba de vacío (doble a) {
System.out.println("Prueba interna(doble) a: " a);
}
}
Sobrecarga de clase { p >
public static void main(String args[]) {
OverloadDemo ob = new OverloadDemo()
int i = 88; ob .test(); ob.test(10, 20);
ob.test(i); // esto invocará test(double)
ob.test(123.2). ) ; // esto invocará test(double)
}
}
El programa produce el siguiente resultado:
Sin parámetros
p>a y b: 10 20
Prueba interior(doble) a: 88
Prueba interior(doble) a: 123,2
En este caso En el ejemplo, test(int) no está definido en esta versión de OverloadDemo. Por lo tanto, cuando se llama a test() con un parámetro entero en Overload, no se encuentra ningún método coincidente. Sin embargo, Java puede convertir automáticamente números enteros a tipos dobles y esta conversión puede resolver este problema. Por lo tanto, después de que no se encuentra test(int), Java expande i para escribir double y luego llama a test(double). Por supuesto, si se define test(int), se llamará primero a test(int) en lugar de test(double). La conversión automática de Java sólo funciona si no se encuentra una coincidencia exacta.
La sobrecarga de métodos admite el polimorfismo porque es una forma en que Java implementa el paradigma de "una interfaz, muchos métodos". Para entender esto, considere el siguiente pasaje: En lenguajes que no admiten la sobrecarga de métodos, cada método debe tener un nombre único. Sin embargo, a menudo desea implementar métodos que tienen diferentes tipos de datos pero que son esencialmente iguales. Puede consultar el ejemplo de la función de valor absoluto. En los idiomas que no admiten la sobrecarga, suele haber tres o más versiones de esta función, cada una con un nombre ligeramente diferente. Por ejemplo, en el lenguaje C, la función abs() devuelve el valor absoluto de un número entero, labs() devuelve el valor absoluto de un entero largo ( ) y fabs() devuelve el valor absoluto de un valor de punto flotante.
Aunque las funciones de estas tres funciones son esencialmente las mismas, debido a que el lenguaje C no admite la sobrecarga, cada función debe tener su propio nombre. Esto hace que la situación conceptual sea mucho más complicada. Aunque el concepto subyacente de cada función es el mismo, aún debes recordar estos tres nombres. Esto no sucede en Java, porque todas las funciones de valor absoluto pueden usar el mismo nombre. De hecho, la biblioteca de clases estándar de Java contiene un método de valor absoluto llamado abs(). Este método está sobrecargado por la clase matemática de Java para manejar tipos numéricos. Java determina la versión de abs() llamada según el tipo de parámetro.
El valor de la sobrecarga es que permite acceder a métodos relacionados usando el mismo nombre. Por tanto, el nombre abs representa la acción general que realiza. Es trabajo del compilador elegir la versión específica correcta para un entorno particular. Como programador, sólo necesitas recordar las operaciones comunes a realizar. Mediante la aplicación del polimorfismo, varios nombres se reducen a uno. Aunque este ejemplo es bastante simple, si amplía este concepto, comprenderá que la sobrecarga puede ayudarlo a resolver problemas más complejos.
Cuando sobrecargas un método, cada versión del método puede realizar cualquier acción que desees. No existe ningún requisito de que los métodos sobrecargados deban estar relacionados entre sí. Sin embargo, estilísticamente, la sobrecarga de métodos todavía implica una relación. Es por eso que cuando puedes sobrecargar métodos no relacionados con el mismo nombre, no deberías hacerlo. Por ejemplo, podría utilizar el nombre sqr para crear un método que devuelva el cuadrado de un número entero y la raíz cuadrada de un número de punto flotante. Pero las dos operaciones son funcionalmente diferentes. Aplicar un método de esta manera anula su propósito original. En la programación real, sólo debes sobrecargar operaciones que estén estrechamente relacionadas entre sí.
7.1.1 Sobrecarga de constructores
Además de sobrecargar métodos normales, también se pueden sobrecargar constructores. De hecho, para la mayoría de las clases reales que crea, sobrecargar los constructores es la norma, no la excepción. Para entender por qué es así, recordemos el ejemplo de la clase Box del capítulo anterior. El siguiente es un ejemplo de la última versión de la clase Box:
class Box { doble ancho; doble altura;
// Este es el constructor de Box <. /p>
Box(doble w, doble h, doble d) {ancho = w; alto = h;
}
// calcular y devolver; volumen doble volumen() { return ancho * alto * profundidad }}
En este ejemplo, el constructor Box() requiere tres argumentos, lo que significa que todos los objetos Box definidos deben pasarse a Box(). constructor tres parámetros. Por ejemplo, la siguiente declaración no es válida en la situación actual:
Box ob = new Box();
Porque Box() requiere tres parámetros, si no hay parámetros, es un error al llamarlo. Esto plantea algunas preguntas importantes. ¿Qué pasa si sólo quieres una caja y no te importa (o no conoces) sus dimensiones originales? ¿O qué sucede si desea inicializar un cubo con un solo valor que pueda usarse para sus tres dimensiones? Si la clase Box se escribiera como está ahora, no tendría forma de resolver otros problemas como este, porque sólo puede tomar tres parámetros y no tiene otras opciones.
Afortunadamente, la solución a estos problemas es bastante sencilla: sobrecargar el constructor de Box para que maneje la situación que acabamos de describir.
El siguiente programa es una versión mejorada de Box, que utiliza la sobrecarga del constructor de Box para resolver estos problemas:
/* Aquí, Box define tres constructores para inicializar
las dimensiones de un cuadro de varias maneras.
*/
clase Caja {
doble ancho; doble altura; doble profundidad; w, doble h, doble d) {
ancho = w;
alto = h
profundidad =
}
// constructor usado cuando no se especifican dimensiones Box() { width = -1; // usa -1 para indicar
height = -1 // un
profundidad = -1; // caja
}
// constructor utilizado cuando se crea el cubo Box(double len) { ancho = alto = profundidad = len;}
// calcular y devolver volumen double volume() { return ancho * alto * profundidad;}}
clase OverloadCons {
public static void main(String args[]) { // crea cuadros usando los distintos constructoresBox mybox1 = new Box(10, 20, 15); Box mybox2 = new Box(); Box mycube = new Box(7); vol;
// obtener el volumen del primer cuadro
vol = mybox1.volume();
System.out.println("El volumen de mybox1 es " vol);
// obtener el volumen de la segunda caja
vol = mybox2.volume();
System.out.println("El volumen de mybox2 es " vol);
// obtener el volumen del cubo
vol = mycube.volume();
System.out.println("El volumen de mycube es " vol);
}
}
El resultado producido por este programa es el siguiente:
El volumen de mybox1 es 3000,0
El volumen de mybox2 es -1,0
<p>El volumen de mycube es 343.0
En este ejemplo, cuando se ejecuta new, se llama al constructor apropiado según los argumentos especificados.