Sobrecarga de métodos en Java

Intermedio POO

En esta sección, aprenderá acerca de una de las características más interesantes de Java: la sobrecarga de métodos. En Java, dos o más métodos dentro de la misma clase pueden compartir el mismo nombre, siempre que sus declaraciones de parámetros sean diferentes.

Cuando este es el caso, se dice que los métodos están sobrecargados, y el proceso se denomina sobrecarga de métodos (method overloading). La sobrecarga de métodos es una de las formas en que Java implementa polimorfismo.

1. Cómo sobrecargar un método

En general, para sobrecargar un método, simplemente declare versiones diferentes de él. El compilador se ocupa del resto. Debe observar una restricción importante: el tipo y/o el número de parámetros de cada método sobrecargado debe diferir. No es suficiente que dos métodos difieran solo en sus tipos de devolución.

Los tipos de devolución no proporcionan información suficiente en todos los casos para que Java decida qué método utilizar.

Por supuesto, los métodos sobrecargados también pueden diferir en sus tipos de devolución. Cuando se llama a un método sobrecargado, se ejecuta la versión del método cuyos parámetros coinciden con los argumentos. Aquí hay un ejemplo simple que ilustra la sobrecarga de métodos:

// Programa de demostración de sobrecarga de métodos

class Sobrecarga{
    void demoSobrec(){
        System.out.println("Sin parámetros\n");
    }

    //Sobrecargando demoSobrec para un parámetro int
    void demoSobrec(int a){
        System.out.println("Un parámetro: " +a+"\n");
    }

    //Sobrecargando demoSobrec para dos parámetros int
    int demoSobrec(int a, int b){
        System.out.println("Dos parámetros: "+a+", "+b);
        return a+b;
    }

    //Sobrecargando demoSobrec para dos parámetros double
    double demoSobrec(double a, double b){
        System.out.println("Dos parámetros tipo double: "+a+", "+b);
        return a+b;
    }
}

class DemoSobrecarga{
    public static void main(String[] args) {
        Sobrecarga sc= new Sobrecarga();
        int sumaint;
        double sumadouble;

        //Llamando todas las versiones de demoSobrec
        sc.demoSobrec();

        sc.demoSobrec(2);

        sumaint=sc.demoSobrec(4,6);
        System.out.println("Resultado de demoSobrec(4,6) es: "+sumaint+"\n");

        sumadouble=sc.demoSobrec(1.1,2.2);
        System.out.println("Resultado de demoSobrec(1.1,2.2) es: "+sumadouble);

    }
}

Salida:

Sin parámetros

Un parámetro: 2

Dos parámetros: 4, 6
Resultado de demoSobrec(4,6) es: 10

Dos parámetros tipo double: 1.1, 2.2
Resultado de demoSobrec(1.1,2.2) es: 3.3000000000000003

Como puede ver, demoSobrec() está sobrecargado cuatro veces. La primera versión no toma parámetros, la segunda toma un parámetro entero, la tercera toma dos parámetros enteros (int), y la cuarta toma dos parámetros double.

Observe que las primeras dos versiones de ovlDemo() no devuelven nada, y las otras dos devuelven un valor. Esto es perfectamente válido, pero tal como se explicó, la sobrecarga no se ve afectada en un sentido u otro por el tipo de devolución de un método. Por lo tanto, intentar utilizar las dos versiones siguientes de demoSobrec() provocará un error:

void demoSobrec(int a){
   System.out.println("Un parámetro: " +a);
   }

int demoSobrec(int a){
   System.out.println("Un parámetro: " +a);
   return a;
   }

La diferencia en sus tipos de devolución es insuficiente para el propósitos de sobrecarga.

2. Conversiones de tipo automáticas

Como recordará anteriormente en Conversión de tipos de datos, Java proporciona ciertas conversiones de tipo automáticas. Estas conversiones también se aplican a los parámetros de métodos sobrecargados. Por ejemplo, considere lo siguiente:

// Conversiones automáticas de tipo
// en métodos sobrecargados

class Sobrecarga{
   void mitipo (int x){
       System.out.println("Mi tipo (int): "+x);
   }

   void mitipo(double x){
       System.out.println("Mi tipo (double): "+x);
   }

}

class DemoSobrecarga{
    public static void main(String[] args) {
        Sobrecarga sc= new Sobrecarga();

        int i=10;
        double d= 10.1;

        byte b= 99;
        short s=10;
        float f=11.5F;

        sc.mitipo(i);
        sc.mitipo(d);

        sc.mitipo(b); //Conversión de tipo, llamando a sc.mitipo(int)
        sc.mitipo(s); //Conversión de tipo, llamando a sc.mitipo(int)
        sc.mitipo(f); //Conversión de tipo, llamando a sc.mitipo(double)
    }
}

Salida:

Mi tipo (int): 10
Mi tipo (double): 10.1
Mi tipo (int): 99
Mi tipo (int): 10
Mi tipo (double): 11.5

En este ejemplo, sólo dos versiones de mitipo() están definidos: uno que tiene un parámetro de tipo int y otro que tiene un tipo double. Sin embargo, es posible pasar un valor de tipo byte, short, o float a mitipo(). En el caso de byte y short, Java automáticamente convierte a int. Así, mitipo(int) se invoca. En el caso de la float, el valor se convierte a double y mitipo(double) es llamado.

Es importante entender, sin embargo, que la conversión automática sólo se aplican si no hay ninguna coincidencia directa entre un parámetro y argumento. Por ejemplo, aquí está el programa anterior con la adición de una versión de f ( ), que especifica un parámetro byte:

class Sobrecarga{

   // Agrego mitipo(byte)
   void mitipo (byte x){
       System.out.println("Mi tipo (byte): "+x);
   }

    void mitipo (int x){
        System.out.println("Mi tipo (int): "+x);
    }

   void mitipo(double x){
       System.out.println("Mi tipo (double): "+x);
   }

}

class DemoSobrecarga{
    public static void main(String[] args) {
        Sobrecarga sc= new Sobrecarga();

        int i=10;
        double d= 10.1;

        byte b= 99;
        short s=10;
        float f=11.5F;

        sc.mitipo(i);
        sc.mitipo(d);

        sc.mitipo(b); //NO HAY CONVERSION DE TIPO
        sc.mitipo(s); //Conversión de tipo, llamando a sc.mitipo(int)
        sc.mitipo(f); //Conversión de tipo, llamando a sc.mitipo(double)
    }
}

Salida:

Mi tipo (int): 10
Mi tipo (double): 10.1
Mi tipo (byte): 99
Mi tipo (int): 10
Mi tipo (double): 11.5

En esta versión, ya que hay una versión de mitipo() que toma un byte de argumento, cuando mitipo() se llama con un byte de argumento, mitipo(byte) se invoca y la conversión automática a int no se produce.

3. Introducción a Polimorfismo

La sobrecarga de métodos soporta el polimorfismo porque es una de las formas en que Java implementa el paradigma de “una interfaz, múltiples métodos“.

Para comprender cómo, considere lo siguiente: En los lenguajes que no admiten la sobrecarga de métodos, a cada método se le debe asignar un nombre único. Sin embargo, frecuentemente querrá implementar esencialmente el mismo método para diferentes tipos de datos.

Considere la función de valor absoluto. En los lenguajes que no admiten la sobrecarga, usualmente hay tres o más versiones de esta función, cada una con un nombre ligeramente diferente. Por ejemplo, en C, la función abs() devuelve el valor absoluto de un entero, labs() devuelve el valor absoluto de un entero largo, y fabs() devuelve el valor absoluto de un valor de coma flotante. Como C no admite sobrecarga, cada función debe tener su propio nombre, aunque las tres funciones hacen esencialmente lo mismo.

Esto hace que la situación sea más compleja, conceptualmente, de lo que realmente es. Aunque el concepto subyacente de cada función es el mismo, todavía tiene tres nombres para recordar. Esta situación no ocurre en Java, porque cada método de valor absoluto puede usar el mismo nombre. De hecho, la biblioteca de clases estándar de Java incluye un método de valor absoluto, llamado abs(). Este método está sobrecargado por la clase Math de Java para manejar todos los tipos numéricos. Java determina qué versión de abs() llamar en función del tipo de argumento.

4. Preguntas Frecuentes

En Java, una firma es el nombre de un método más su lista de parámetros. Por lo tanto, para fines de sobrecarga, no hay dos métodos dentro de la misma clase que puedan tener la misma firma. Tenga en cuenta que una firma no incluye el tipo de devolución, ya que Java no lo utiliza para la resolución de sobrecarga.
La respuesta es ‘Sí’. Podemos tener dos o más métodos estáticos con el mismo nombre, pero se diferencian en los parámetros de entrada.
No podemos sobrecargar dos métodos en Java si difieren solo por palabra clave static (si el número de parámetros y tipos de parámetros es el mismo).
Overloading significa que un mismo método tiene diferentes firmas. Overriding es el mismo método, misma firma pero diferentes clases conectadas a través de la herencia. La sobrecarga es un ejemplo de polimorfismo en tiempo de compilación y la sobreescritura es un ejemplo de polimorfismo en tiempo de ejecución.
Al igual que otros métodos estáticos, sí podemos sobrecargar main() en Java.

Ejemplo: Sobrecarga del método main

class DemoSobrecarga{
    // El método main()
    public static void main(String[] args) {
        System.out.println("Hola Javeros (desde el main)");
        DemoSobrecarga.main("Java");
    }

    // Sobrecargando el método main()
    public static void main(String arg1) {
        System.out.println("Hola, " + arg1);
        DemoSobrecarga.main("Java desde Cero","Sobrecarga de métodos");
    }
    public static void main(String arg1, String arg2) {
        System.out.println("Hola, " + arg1 + ", " + arg2);
    }
}

Salida:

Hola Javeros (desde el main)
Hola, Java
Hola, Java desde Cero, Sobrecarga de métodos

5. Conclusión

Cuando sobrecarga un método, cada versión de ese método puede realizar cualquier actividad que desee. No hay ninguna regla que establezca que los métodos sobrecargados deben relacionarse entre sí. Sin embargo, desde un punto de vista estilístico, la sobrecarga de métodos implica una relación.

Por lo tanto, aunque puede usar el mismo nombre para sobrecargar métodos no relacionados, no debería hacerlo. 

Por ejemplo, podría usar el nombre sqr para crear métodos que devuelvan el cuadrado de un entero y la raíz cuadrada de un valor de coma flotante. Pero estas dos operaciones son fundamentalmente diferentes. Aplicar la sobrecarga de métodos de esta manera frustra su propósito original. En la práctica, debe sobrecargar solo operaciones estrechamente relacionadas.

Métodos en Java
  • Sobrecarga de métodos

Sobre el Autor:

Hey hola! Yo soy Alex Walton y tengo el placer de compartir conocimientos hacía ti sobre el tema de Programación en Java, desde cero, Online y Gratis.

1 comentario

  1. Anonymus

    Aber quiero comentar algo y es que cuando uno usa una interfas lo que ase es sobreescribir los metodos de dicha interfas en ningun mometo se ase sobrecarga de metodos.Ademas no beo ningun similitud sobre el polimorfismo ya que el polimorfismo se refiere a diferentes foramas diferente comportamiento y es aplicada en la sobreescritura de metodos no en la sobrecarga.Ya que el polimorfismo esta intimamente relasionada con la Herencia y en la sobrecarga para usarla no ase falta usar ningun tipo de Herencia .

Deja una Respuesta

*

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.