CodeGym /Cursos /JAVA 25 SELF /Sobrecarga de métodos (overloading)

Sobrecarga de métodos (overloading)

JAVA 25 SELF
Nivel 18 , Lección 1
Disponible

1. Sobrecarga de métodos

La sobrecarga de métodos (method overloading) es la posibilidad de declarar en una misma clase varios métodos con el mismo nombre, pero con listas de parámetros diferentes (tipos, cantidad u orden de los argumentos). Cuando llamas a un método así, el compilador decide por sí mismo qué versión utilizar en función de los argumentos pasados.

Analogía de la vida real

Imagina que llamas al servicio de atención de un banco. Puedes marcar números distintos — para particulares, para empresas, para clientes VIP. Los números son diferentes, pero el objetivo es el mismo — obtener ayuda. En programación, la sobrecarga de métodos es como un único número de soporte que te conecta automáticamente con el operador adecuado en función de cuál sea tu consulta (o qué parámetros hayas pasado).

Sintaxis de la sobrecarga en Java

En Java, la sobrecarga de métodos se implementa de forma muy sencilla: declaras varios métodos con el mismo nombre, pero con parámetros distintos.

Regla importante:
La sobrecarga se diferencia únicamente por la lista de parámetros (tipo, cantidad, orden).
¡No se permite sobrecargar solo por el tipo de retorno!
El compilador no podrá distinguir los métodos si tienen el mismo nombre y los mismos parámetros, aunque el tipo de retorno sea diferente.

Ejemplo sencillo

public class Printer {
    // Imprimir un número entero
    void print(int x) {
        System.out.println("int: " + x);
    }

    // Imprimir una cadena
    void print(String s) {
        System.out.println("String: " + s);
    }

    // Imprimir dos números
    void print(int x, int y) {
        System.out.println("int, int: " + x + ", " + y);
    }
}

Uso:

Printer printer = new Printer();
printer.print(42);           // llamará a print(int x)
printer.print("Hello!");     // llamará a print(String s)
printer.print(5, 10);        // llamará a print(int x, int y)

El compilador determina por sí mismo qué método invocar en función de los argumentos proporcionados.

2. Cómo el compilador elige el método necesario

Cuando llamas a un método sobrecargado, el compilador analiza la lista de argumentos y busca la versión más adecuada.

Criterios de selección:

  • Coincidencia en la cantidad de argumentos.
  • Coincidencia en el tipo de cada argumento (o posibilidad de convertir el tipo, por ejemplo, int double).
  • Si encajan varios métodos, se elige el más específico.

Ejemplo:

public class OverloadDemo {
    void show(int x) {
        System.out.println("show(int): " + x);
    }

    void show(double x) {
        System.out.println("show(double): " + x);
    }

    public static void main(String[] args) {
        OverloadDemo demo = new OverloadDemo();
        demo.show(5);      // show(int): 5
        demo.show(5.5);    // show(double): 5.5
    }
}

Si llamas a demo.show(5), el compilador elegirá show(int). Si llamas con 5.5, elegirá show(double).

Conversiones de tipos

Si no existe un método adecuado, el compilador intentará convertir los tipos de los argumentos (por ejemplo, int double), pero solo si es posible y no hay ambigüedad.

void print(double x) { /* ... */ }

print(5); // int 5 se convierte a double 5.0

La sobrecarga solo por tipo de retorno — ¡no funciona!

Muchos principiantes intentan hacer esto:

// Error: no es posible este tipo de sobrecarga
int sum(int x, int y) { return x + y; }
double sum(int x, int y) { return (double) (x + y); }

El compilador no sabrá qué método quieres invocar si simplemente escribes sum(2, 3).
Recuerda: ¡la sobrecarga de métodos solo es posible por los parámetros, no por el tipo de retorno!

3. Sobrecarga de constructores

¡Se pueden sobrecargar no solo los métodos normales, sino también los constructores!

public class Person {
    String name;
    int age;

    // Constructor solo con nombre
    public Person(String name) {
        this.name = name;
        this.age = 0; // por defecto
    }

    // Constructor con nombre y edad
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

Uso:

Person p1 = new Person("Anna");
Person p2 = new Person("Boris", 25);

4. Ejemplos prácticos

Calculator con sobrecarga

Escribamos la clase Calculator, que sabe sumar números de distinto tipo y cantidad.

public class Calculator {
    // Suma de dos enteros
    int add(int a, int b) {
        return a + b;
    }

    // Suma de tres enteros
    int add(int a, int b, int c) {
        return a + b + c;
    }

    // Suma de dos double
    double add(double a, double b) {
        return a + b;
    }
}

Uso:

Calculator calc = new Calculator();

System.out.println(calc.add(2, 3));         // 5
System.out.println(calc.add(1, 2, 3));      // 6
System.out.println(calc.add(2.5, 3.1));     // 5.6

Sobrecarga de métodos en la biblioteca estándar

Ya te has encontrado con la sobrecarga, incluso si no te diste cuenta. Por ejemplo, el método println en System.out está sobrecargado para distintos tipos:

System.out.println("Hello");   // println(String)
System.out.println(123);       // println(int)
System.out.println(3.14);      // println(double)
System.out.println(true);      // println(boolean)

Abre el código fuente de la clase PrintStream — verás decenas de versiones sobrecargadas de println.

5. Cuándo usar la sobrecarga

La sobrecarga de métodos es una herramienta potente, pero conviene aplicarla con cabeza. Es útil cuando:

  • La lógica del método es la misma, pero los parámetros pueden diferir.
  • Quieres que el API de la clase sea más amigable y flexible.
  • Necesitas mantener variantes antiguas y nuevas de invocación del método.

Ejemplo práctico:
En nuestra aplicación educativa (por ejemplo, un gestor de tareas) se puede implementar un método para añadir una tarea con distintos parámetros:

public class TaskManager {
    void addTask(String description) { ... }
    void addTask(String description, int priority) { ... }
    void addTask(String description, int priority, String deadline) { ... }
}

Este enfoque no solo es cómodo para quien usa tu código, sino que también hace que tu clase sea flexible ante cambios futuros.

6. Sobrecarga y varargs (número variable de argumentos)

En Java es posible declarar un método con un número variable de parámetros mediante ... (varargs):

void printAll(String... messages) {
    for (String msg : messages) {
        System.out.println(msg);
    }
}

Ahora se puede llamar:

printAll("Hello");
printAll("One", "Two", "Three");

También se puede sobrecargar con varargs, pero ten cuidado: si hay dos métodos y uno de ellos usa varargs y el otro un número fijo de parámetros, el compilador primero intentará encontrar una coincidencia exacta.

7. Errores típicos al sobrecargar métodos

Error n.º 1: Confusión con los tipos de argumentos.
Si tienes los métodos void process(int x) y void process(double x), la llamada process(5) invocará la primera versión, y process(5.0) — la segunda. Pero si llamas a process(5L), el compilador buscará la mejor coincidencia y puede elegir una sobrecarga no obvia (o incluso informar de ambigüedad).

Error n.º 2: Sobrecarga con autoboxing.
Si tienes void foo(Integer x) y void foo(Long x), la llamada foo(5) provocará un error de compilación: el compilador no sabe qué método elegir, porque 5 puede convertirse tanto a Integer como a Long.

Error n.º 3: Sobrecarga solo por tipo de retorno.
Como ya se dijo arriba, los métodos que se diferencian únicamente por el tipo de retorno no se pueden sobrecargar.

Error n.º 4: Sobrecarga y herencia.
Si en la clase base hay un método y en la subclase declaras un método con el mismo nombre pero otra firma, esto será una sobrecarga y no una sobreescritura. ¡Esto se confunde a menudo! Más detalles en la siguiente lección.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION