Java
Métodos: parámetros, retorno y sobrecarga
Cómo empaquetar código reutilizable en métodos, con parámetros, valores de retorno y sobrecarga.
El problema: código repetido
El ejercicio de los pares de la página anterior imprime números del 1 al 10. Si quisieras hacer lo mismo del 1 al 20, y después del 1 al 100, terminarías copiando el mismo bucle una y otra vez, cambiando solo el límite. Un método empaqueta ese código una vez y permite volver a usarlo, pasándole lo que cambia cada vez como parámetro.
Declarar un método
public class Main {
static void saludar(String nombre) {
System.out.println("Hola, " + nombre + "!");
}
public static void main(String[] args) {
saludar("Ana");
saludar("Beto");
}
}Hola, Ana!
Hola, Beto!saludar se define fuera de main, pero dentro de la misma clase — en Java, un método siempre vive dentro de una clase, igual que main. La firma tiene las mismas piezas que ya viste en main:
| Parte | Qué significa |
|---|---|
static | El método pertenece a la clase, no requiere crear un objeto para llamarlo (más sobre esto en la página de clases). |
void | No devuelve ningún valor. |
saludar | El nombre del método. |
(String nombre) | Un parámetro: un valor que el método recibe cada vez que se lo llama. |
Cada llamada (saludar("Ana"), saludar("Beto")) le pasa un argumento distinto, y el método usa ese valor internamente sin que haya que reescribir nada.
“Parámetro” y “argumento” a veces se usan como sinónimos, pero técnicamente el parámetro es el nombre en la declaración del método (nombre), y el argumento es el valor concreto que se pasa en cada llamada ("Ana", "Beto"). No suele haber problema en confundirlos en una conversación, pero vale la pena reconocer la diferencia si aparece en un mensaje de error.
Métodos que devuelven un valor
return se traduce literalmente como “devolver” o “retornar” — y hace exactamente eso: un método puede calcular algo y devolverlo con return, en vez de solo imprimir. Es como pedirle a alguien que te haga un mandado y te lo traiga de vuelta, en vez de que simplemente muestre el resultado y se lo quede:
static int sumar(int a, int b) {
return a + b;
}Aquí void cambia por int: ese es el tipo del valor que el método promete devolver. Todo camino posible dentro del método tiene que terminar en un return de ese tipo — si el compilador encuentra una forma de salir del método sin pasar por un return, no compila.
public class Main {
static int sumar(int a, int b) {
return a + b;
}
public static void main(String[] args) {
int resultado = sumar(3, 4);
System.out.println(resultado);
}
}resultado guarda lo que sumar devolvió, exactamente igual que guardarías cualquier otro valor calculado.
return corta la ejecución del método en el momento en que se ejecuta — cualquier línea después de un return alcanzado nunca corre. Esto es útil a propósito para salidas anticipadas (por ejemplo, devolver un valor especial ni bien detectas un caso inválido), pero también es una fuente de bugs si no es intencional.
Sobrecarga de métodos
Java permite tener varios métodos con el mismo nombre, siempre que se puedan distinguir por sus parámetros (cantidad o tipo distintos). Esto se llama sobrecarga (overloading):
static int sumar(int a, int b) {
return a + b;
}
static double sumar(double a, double b) {
return a + b;
}
static int sumar(int a, int b, int c) {
return a + b + c;
}Cuando llamas a sumar(...), el compilador elige automáticamente cuál de las tres versiones corresponde según los argumentos que le pasaste — sumar(2, 3) usa la primera, sumar(2.5, 3.5) usa la segunda, sumar(1, 2, 3) usa la tercera.
La sobrecarga se decide por la firma del método (nombre + tipos de parámetros), no por el nombre solo ni por el tipo de retorno. No puedes tener dos métodos con exactamente el mismo nombre y los mismos parámetros aunque devuelvan tipos distintos — el compilador no tiene forma de saber cuál llamaste.
System.out.println que ya usaste en cada ejemplo es en sí un método sobrecargado: por eso funciona igual de bien con un String, un int o un boolean — hay una versión distinta de println para cada tipo, y Java elige la que corresponde.
Pon a prueba
¿Qué imprime este programa?
public class Main {
static int triple(int x) {
if (x < 0) {
return 0;
}
return x * 3;
}
public static void main(String[] args) {
System.out.println(triple(4));
System.out.println(triple(-2));
}
}Imprime 12 y después 0. triple(4) no entra al if (4 no es menor que 0), así que sigue hasta return x * 3, que da 12. triple(-2) sí entra al if porque -2 es negativo, ejecuta return 0 ahí mismo, y el método termina — la línea return x * 3 nunca se alcanza para ese llamado.
Ordena las líneas para declarar un método que calcule el promedio de dos notas y usarlo en main.
- System.out.println(resultado);
- }
- public class Main {
- double resultado = promedio(7.5, 8.5);
- return (a + b) / 2;
- public static void main(String[] args) {
- static double promedio(double a, double b) {
- }
- }
Siguiente paso
Los métodos empaquetan comportamiento, pero hasta ahora solo trabajaste con una variable a la vez. Para manejar colecciones de valores — una lista de notas, no una sola — sigue con Arrays y ArrayList.