Sobrecarga de constructores y métodos en Java

Sobrecarga de constructores y métodos en Java

En el capítulo anterior del curso Java, expliqué un poco como funcionaba la herencia de clases. En este capítulo del curso de Java, te voy a mostrar como utilizar y lo que es la sobrecarga de métodos y constructores.


Sobrecarga de métodos constructores de Java

En una misma clase, podemos tener varios métodos constructores, aunque de primeras, esto no parece posible si caemos en la cuenta de que el método constructor de una clase, es el que lleva el mismo nombre de la clase. Aquí un ejemplo:

class Usuario {
    public String nombre;
    String apellidos;
    int edad;
    String direccion;
    String telefono;

    // constructor de la clase
    public Usuario(String nombre, String apellidos, int edad, String direccion, String telefono) {
        this.nombre = nombre;
        this.apellidos = apellidos;
        this.edad = edad;
        this.direccion = direccion;
        this.telefono = telefono;
    }

    //Método para mostrar la información del constructor
    public void mostrarDatos() {
        System.out.println("Nombre: " + nombre);
        System.out.println("Apellidos: " + apellidos);
        System.out.println("Edad: " + edad);
        System.out.println("Dirección: " + direccion);
        System.out.println("Teléfono: " + telefono);
    }
  
}

En la línea 10, puedes apreciar el nombre, que es el mismo que el de la clase.

Creando otro método constructor para la clase

Para crear más métodos constructores, lo puedes hacer sencillamente, creando otro con el mismo nombre de la clase. Esto hará que haya una sobrecarga de métodos constructores.

class Usuario {
    public String nombre;
    String apellidos;
    int edad;
    String direccion;
    String telefono;

    // constructor de la clase
    public Usuario(String nombre, String apellidos, int edad, String direccion, String telefono) {
        this.nombre = nombre;
        this.apellidos = apellidos;
        this.edad = edad;
        this.direccion = direccion;
        this.telefono = telefono;
    }

    public Usuario(String nombre, String apellidos) {
        this.nombre = nombre;
        this.apellidos = apellidos;
    }

    //Método para mostrar la información del constructor
    public void mostrarDatos() {
        System.out.println("Nombre: " + nombre);
        System.out.println("Apellidos: " + apellidos);
        System.out.println("Edad: " + edad);
        System.out.println("Dirección: " + direccion);
        System.out.println("Teléfono: " + telefono);
        System.out.println("Tipo de usuario: " + tipoUsuario);
    }

}

En la línea 18, tienes una sobrecarga del método constructor "Usuario". Este es una versión reducida para crear los objetos, con solo dos argumentos. Ahora, podemos usar las dos formas:


class Usuario {
  	// Atributos
    public String nombre;
    String apellidos;
    int edad;
    String direccion;
    String telefono;

    // constructor de la clase
    public Usuario(String nombre, String apellidos, int edad, String direccion, String telefono) {
        this.nombre = nombre;
        this.apellidos = apellidos;
        this.edad = edad;
        this.direccion = direccion;
        this.telefono = telefono;
    }
	// Constructor reducido
    public Usuario(String nombre, String apellidos) {
        this.nombre = nombre;
        this.apellidos = apellidos;
    }

    //Método para mostrar la información del constructor
    public void mostrarDatos() {
        System.out.println("Nombre: " + nombre);
        System.out.println("Apellidos: " + apellidos);
        System.out.println("Edad: " + edad);
        System.out.println("Dirección: " + direccion);
        System.out.println("Teléfono: " + telefono);
    }

}


public class Main {
    public static void main(String[] args) {
        Usuario usuario1 = new Usuario("Olga", "Izquierdo García", 56, "Av. del Mediterráneo, 85", "+34-91-000-0000");
        usuario1.mostrarDatos();
    }
}

Cuando llamamos al método mostrar datos, vemos que no hay ningún problema. Salen todos.

Resultado en la consola

Nombre: Olga
Apellidos: Izquierdo García
Edad: 56
Dirección: Av. del Mediterráneo, 85
Teléfono: +34-91-000-0000

De momento, hemos utilizado el constructor de 5 parámetros, el primero.

Ahora, probemos creando un objeto con el constructor reducido, el cual, va a tener solo el nombre y los apellidos.

Java, sabe cuál usar en torno al número de argumentos que le pasemos a la instancia.

Por eso, si creas dos constructores con el mismo número de parámetros, te va a dar el error de que el constructor ya está definido.

Error en la consola

'Usuario(String, String, int, String, String)' is already defined in 'Usuario'
Usuario usuario1 = new Usuario("Olga", "Izquierdo García");
usuario1.mostrarDatos();

El problema que tenemos, es que al crear un objeto así, si no asignamos valores después a los demás atributos, tenemos una salida en la consola con valores null (y cero en el caso del int (atributo edad)).

Resultado en la consola

Nombre: Olga
Apellidos: Izquierdo García
Edad: 0
Dirección: null
Teléfono: null

Sobrecarga de métodos en Java

Pues es aquí, donde llegamos a la sobrecarga de métodos de Java. Los métodos normales, también pueden sobrecargarse. Solo hay que crear otro con el mismo nombre, al igual que hacemos con el constructor. Así, tendremos un método que mostrará el reporte completo y otro que no, solo con el nombre y apellidos.

También te digo, que podrías hacer esto, crear dos métodos diferentes para cada caso:

//Método para mostrar la información del primer constructor 
public void mostrarDatosCompletos() {
        System.out.println("Nombre: " + nombre);
        System.out.println("Apellidos: " + apellidos);
        System.out.println("Edad: " + edad);
        System.out.println("Dirección: " + direccion);
        System.out.println("Teléfono: " + telefono);
    }

//Método para mostrar la información del segundo constructor
    public void mostrarDatosReducidos() {
        System.out.println("Nombre: " + nombre);
        System.out.println("Apellidos: " + apellidos);
    }
}
public class Main {
    public static void main(String[] args) {
        Usuario usuario1 = new Usuario("Olga", "Izquierdo García", 56, "Av. del Mediterráneo, 85", "+34-91-000-0000");
        usuario1.mostrarDatosCompletos();
    }
}

Resultado en la consola

Nombre: Olga
Apellidos: Izquierdo García
Edad: 56
Dirección: Av. del Mediterráneo, 85
Teléfono: +34-91-000-0000
public class Main {
    public static void main(String[] args) {
        Usuario usuario1 = new Usuario("Olga", "Izquierdo García", 56, "Av. del Mediterráneo, 85", "+34-91-000-0000");
        usuario1.mostrarDatosReducidos();
    }
}

Resultado en la consola

Nombre: Olga
Apellidos: Izquierdo García

La otra forma es utilizar la sobrecarga de métodos:

   public void mostrarDatos() {
        System.out.println("Nombre: " + nombre);
        System.out.println("Apellidos: " + apellidos);
        System.out.println("Edad: " + edad);
        System.out.println("Dirección: " + direccion);
        System.out.println("Teléfono: " + telefono);
        //System.out.println("Tipo de usuario: " + tipoUsuario);
    }

    //Método para mostrar la información del segundo constructor
    public void mostrarDatos() {
        System.out.println("Nombre: " + nombre);
        System.out.println("Apellidos: " + apellidos);
        System.out.println("Tipo de usuario: " + tipoUsuario);
    }
}

No obstante, nos topamos con un problema. Estos métodos son solo para imprimir en la consola, por lo que no tienen parámetros. Y eso significa, que tienen el mismo número de parámetros (cero) y no pueden sobrecargarse:

Error en la consola

'mostrarDatos()' is already defined in 'Usuario'

Entonces, tenemos que añadirle a uno de los dos un parámetro. Si no necesitas ninguno, puedes optar por poner un boolean, si en la llamada le das un valor 'true' o 'false', ejecutará el método completo y si no, si no le das argumento alguno, ejecutará el método reducido:

    //Método para mostrar la información del primer constructor
    public void mostrarDatos(Boolean completo) {
        System.out.println("Nombre: " + nombre);
        System.out.println("Apellidos: " + apellidos);
        System.out.println("Edad: " + edad);
        System.out.println("Dirección: " + direccion);
        System.out.println("Teléfono: " + telefono);
    }

    //Método para mostrar la información del segundo constructor
    public void mostrarDatos() {
        System.out.println("Nombre: " + nombre);
        System.out.println("Apellidos: " + apellidos);
    }
}

Y te digo un boolean por poner algo, puede ser cualquier cosa, solo que no tengan el mismo número de parámetros.

public class Main {
    public static void main(String[] args) {
        Usuario usuario1 = new Usuario("Olga", "Izquierdo García");
        usuario1.mostrarDatos();
    }
}

Resultado en la consola

Nombre: Olga
Apellidos: Izquierdo García

Después, si queremos el reporte completo con un usuario que tiene todos los valores iniciales, lo hacemos como te he indicado, con un valor booleano en la llamada:

    public static void main(String[] args) {
        Usuario usuario1 = new Usuario("Olga", "Izquierdo García", 56, "Av. del Mediterráneo, 85", "+34-91-000-0000");
        usuario1.mostrarDatos(true);
    }
}

Resultado en la consola

Nombre: Olga
Apellidos: Izquierdo García
Edad: 56
Dirección: Av. del Mediterráneo, 85
Teléfono: +34-91-000-0000

Sobrecarga de métodos en herencia de clases Java

Ahora, creemos una clase más, se va a llamar "Empleado" y será subclase de "Usuario".

class Empleado extends Usuario {


}

Ahora, heredaremos los dos constructores de la clase Usuario, para poder usarlos también en esta clase.

Para heredar, lo tienes que hacer de la forma que vimos en el capítulo anterior:

class Empleado extends Usuario {

    public Empleado(String nombre, String apellidos, int edad, String direccion, String telefono) {
        super(nombre, apellidos, edad, direccion, telefono);
    }

    public Empleado(String nombre, String apellidos) {
        super(nombre, apellidos);
    }
}

Puedes escribir esto a mano, o utilizar la ayuda de IntelliJ Idea.

sobrecarga de métodos java

Selecciona los constructores que quieras heredar (pulsa CTRL+click) y haz click en "OK".

En mi caso, heredaré ambos.

heredar clases sobrecarga constructores java

Ahora, instanciaremos un usuario de tipo "Empleado". Para ello, escribe "Empleado" después del "new".

public class Main {
    public static void main(String[] args) {
        Usuario usuario1 = new Empleado("Olga", "Izquierdo García", 56, "Av. del Mediterráneo, 85", "+34-91-000-0000");
        usuario1.mostrarDatos(true);
    }
}

Resultado en la consola

Nombre: Olga
Apellidos: Izquierdo García
Edad: 56
Dirección: Av. del Mediterráneo, 85
Teléfono: +34-91-000-0000

Utilicemos el método que utilicemos, funciona.

Lo siguiente, será añadir un atributo de clase más para Usuario, el cual, especificará por defecto un tipo de usuario. Si no se especifica lo contrario, el tipo de usuario será "Sin especificar".

Lo que te interesa de este código (te lo pongo completo por si has perdido un poco el hilo), son las líneas 7, 30 y 37. En ellas, básicamente, declaramos el atributo (línea 7), y mostramos su valor en las líneas 30 y 37.

Ahora mismo, todos los usuarios tienen un "Sin especificar", ya que no se reasigna el valor en ningún caso.


class Usuario {
    public String nombre;
    String apellidos;
    int edad;
    String direccion;
    String telefono;
    String tipoUsuario = "Sin especificar.";

    // constructor de la clase
    public Usuario(String nombre, String apellidos, int edad, String direccion, String telefono) {
        this.nombre = nombre;
        this.apellidos = apellidos;
        this.edad = edad;
        this.direccion = direccion;
        this.telefono = telefono;
    }

    public Usuario(String nombre, String apellidos) {
        this.nombre = nombre;
        this.apellidos = apellidos;
    }

    //Método para mostrar la información del primer constructor
    public void mostrarDatos(Boolean completo) {
        System.out.println("Nombre: " + nombre);
        System.out.println("Apellidos: " + apellidos);
        System.out.println("Edad: " + edad);
        System.out.println("Dirección: " + direccion);
        System.out.println("Teléfono: " + telefono);
        System.out.println("Tipo de usuario: " + tipoUsuario);
    }

    //Método para mostrar la información del segundo constructor
    public void mostrarDatos() {
        System.out.println("Nombre: " + nombre);
        System.out.println("Apellidos: " + apellidos);
        System.out.println("Tipo de usuario: " + tipoUsuario);
    }
}

class Empleado extends Usuario {

    public Empleado(String nombre, String apellidos, int edad, String direccion, String telefono) {
        super(nombre, apellidos, edad, direccion, telefono);
    }

    public Empleado(String nombre, String apellidos) {
        super(nombre, apellidos);
    }
  
}
public class Main {
    public static void main(String[] args) {
        Usuario usuario1 = new Empleado("Olga", "Izquierdo García", 56, "Av. del Mediterráneo, 85", "+34-91-000-0000");
        usuario1.mostrarDatos();
    }
}

Resultado en la consola

Nombre: Olga
Apellidos: Izquierdo García
Tipo de usuario: Sin especificar.

Hay que añadir un sistema para cambiar el valor en los usuarios de tipo "Empleado".

class Empleado extends Usuario {

    public Empleado(String nombre, String apellidos, int edad, String direccion, String telefono) {
        super(nombre, apellidos, edad, direccion, telefono);
        this.tipoUsuario = "Empleado/a";
    }

    public Empleado(String nombre, String apellidos) {
        super(nombre, apellidos);
        this.tipoUsuario = "Empleado/a";
    }
}

Ahora, si instancio un "Empleado", me aparece como tipo de usuario: Empleado/a.

public class Main {
    public static void main(String[] args) {
        Usuario usuario1 = new Empleado("Olga", "Izquierdo García", 56, "Av. del Mediterráneo, 85", "+34-91-000-0000");
        usuario1.mostrarDatos();
    }
}

Resultado en la consola

Nombre: Olga
Apellidos: Izquierdo García
Tipo de usuario: Empleado/a

Y si no es de tipo Empleado…

public class Main {
    public static void main(String[] args) {
        Usuario usuario1 = new Usuario("Olga", "Izquierdo García", 56, "Av. del Mediterráneo, 85", "+34-91-000-0000");
        usuario1.mostrarDatos();
    }
}

Resultado en la consola

Nombre: Olga
Apellidos: Izquierdo García
Tipo de usuario: Sin especificar.

Hasta aquí este capítulo sobre la sobrecarga de métodos y constructores con Java.

No te pierdas nada del curso Máster en Java.


Un comentario en «Sobrecarga de constructores y métodos en Java»

  1. hola espero que estes muy bien me encanta la forma de como nos en señas y te agradezco un montón por todo el contenido gratuito de programación fácil actualmente estoy viendo la clase de JAVA, soy principiante y te confieso que no se si es por mi edad (44) o por que nunca había estudiado nada refente a este tema de programación, pero hay temas que son para mi muy difíciles de entender y sobre todo de memorizar o de retener en mi memoria, me gusta mucho la programación y me encantaría poder ejercerla como empleo en un futuro, podrías darnos algún consejo de estudio con el que pudiéramos entender mejor cada tema ? pienso que hay mas personas que como yo pasamos por este tipo de dificulta, muchas gracias por todo lo que nos compartes y que Dios te bendiga grandemente

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

curso de Python Entrada anterior Decoradores condicionales y expresiones ternarias con Python
php mysql bootstrap Entrada siguiente La concatenación en PHP