Programación Avanzada

Programación Orientada a Objetos

Sobrecarga de métodos

Introducción

En este primer tema del curso, vamos a ver los conceptos de Polimorfismos y Sobrecarga, fundamentales en Programación Orientada a Objetos.

Veremos, también, cuáles son los mecanismos que proporciona el lenguaje de programación Java para trabajar con estos dos conceptos.

Bibliografía

Contenidos

  1. Sobrecarga de métodos.
  2. Sobrecarga de constructores.
  3. Recomendación.
  4. Resumen.

Sobrecarga de métodos

¿Recuerdas el método println(...)?

System.out.println("Hola"); //El argumento es un String

¿Recuerdas que también lo podías utilizar con enteros?

System.out.println(3); //Aquí el argumento es un entero

En POO decimos que el método println(...) está sobrecargado.

Para entender la definición de método sobrecargado necesitamos primero recordar la definición de signatura de un método.

Sobrecarga de métodos

¿Qué diferencia a estos dos métodos?

class Ejemplo {
	...
	public void suma(int a, int b) {...}
	public void multiplica(int a, int b) {...}
	...
}			

El nombre.

Sobrecarga de métodos

¿Y a estos dos?

class Ejemplo {
	...
	public void suma(int a, int b) {...}
	public void suma(int a, int b, int c) {...}
	...
}				

El número de argumentos, ya que su nombre es el mismo.

Sobrecarga de métodos

¿Y a estos otros dos?

class Ejemplo {
	...
	public void suma(int a, int b) {...}
	public void suma(float a, float b) {...}
	...
}				

El tipo de los argumentos, ya que su número es el mismo.

Sobrecarga de métodos

Finalmente, ¿en qué se diferencian estos dos métodos?

class Ejemplo {
	...
	public void suma(int a, int b) {...}
	public int suma(int a, int b) {...}
	...
}				

No se diferencian en nada, el compilador de Java no los distingue.

Recuerda que el tipo de retorno no sirve para distinguir métodos.

Sobrecarga de métodos

Definición:

La signatura de un método lo forma el nombre del método y su lista de argumentos. En la lista de argumentos es importante tanto el tipo de cada uno de los argumentos como su orden dentro de la lista.

Sobrecarga de métodos

Como ejemplo, dentro de la definición de una clase podemos tener:

public void metodo() {...} //Lista de argumentos vacía
public void metodo(int entero) {...} //Un atributo de tipo entero
public void metodo(float real) {...} //Un atributo de tipo float
public void metodo(int entero, float real) {...} //Dos atributos, el primero entero
public void metodo(float real, int entero) {...} //Dos atributos, el primero float

El compilador distingue todos los métodos anteriores.

Veamos algunos ejemplos de uso de estos métodos.

Sobrecarga de métodos

Llamadas no ambiguas a los métodos sobrecargados

metodo(); //Se llama al método con lista de argumentos vacía
metodo(1); //Se llama al método con un entero en la lista de argumentos
metodo(1.0f); //Se llama al método con un float en la lista de argumentos
metodo(1, 1.0f); //Se llama al método con un entero y un float
metodo(1.0f, 1); //Se llama al método con un real y un float

El compilador no tendrá ningún problema con el fragmento de código anterior.

Sobrecarga de métodos

public void metodo() {...} //Lista de argumentos vacía
public void metodo(int entero) {...} //Un atributo de tipo entero
public void metodo(float real) {...} //Un atributo de tipo float
public void metodo(int entero, float real) {...} //Dos atributos, el primero entero
public void metodo(float real, int entero) {...} //Dos atributos, el primero float

¿A qué método se llamará en el siguiente caso?

metodo(1, 1);

Tenemos una ambigüedad no podemos decidir a qué método se llamará.

Sobrecarga de métodos

metodo(1, 1);

Tenemos una ambigüedad no podemos decidir a cual de los siguientes métodos se llamará.


public void metodo(int entero, float real) {...} //Dos atributos, el primero entero
public void metodo(float real, int entero) {...} //Dos atributos, el primero float

Nota: Recuerda las reglas de promoción de tipos.

Sobrecarga de métodos

metodo(1,1);
...
public void metodo(float entero, int real) {...}

Este caso es posible si se promociona el primer 1 a un float.

metodo(1,1);
...
public void metodo(int entero, float real) {...}

Este caso es posible si se promociona el segundo 1 a un float.

Tenemos una ambigüedad.

Sobrecarga de constructores

¿Cómo llamamos al siguiente método?

class Ejemplo {
	Ejemplo() {...}
}			
Es un constructor de la clase.
¿Cómo lo sé?
Tiene el mismo nombre que la clase y sin tipo de retorno.
A este constructor se le llama construtor sin argumentos.

Sobrecarga de constructores

Los constructores también pueden estar sobrecargados.

class Ejemplo {
	Ejemplo() {...}
	Ejemplo(int a) {...}
	Ejemplo(float a) {...}
}			

Sobre ellos funcionan las mismas reglas que sobre el resto de métodos en cuanto a la sobrecarga.

Recomendación

No abuses de la sobrecarga.

La sobrecarga es una herramienta, pero por disponer de ella no la debes usar sin justificación.

Sobrecarga los métodos sólo cuando lo necesites.

Antes de sobrecargar un método pregúntate si hay otra manera de conseguir lo mismo.

Recomendación

class Perona {
  private String nombre;
  private String apellidos;
  private String nif;

  public Persona() { // Constructor sin argumentos
    super();
  }

  public Persona(String nombre) {
    super();
    this.nombre = nombre;
  }

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

Recomendación

    public Persona(String nombre, String apellidos, String nif) {
      super();
      this.nombre = nombre;
      this.apellidos = apellidos;
      this.nif = nif;
    }
  }
            

Recomendación

¿Y el constructor cuando sólo tenemos el nombre y el nif, pero no los apellidos?

    public Persona(String nombre, String nif) {
      super();
      this.nombre = nombre;
      this.nif = nif;
    }

Uff! entra en colisión con el constructor:

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

Recomendación

Lo más aconsejado es definir únicamente el constructor sin argumentos y el que recibe todos los atributos de la clase:

public class Persona {
  ....
  public Persona() { // Constructor sin argumentos
    super();
  }
  public Persona(String nombre, String apellidos, String nif) {
    super();
    this.nombre = nombre;
    this.apellidos = apellidos;
    this.nif = nif;
  }
}

Resumen

La sobrecarga me permite utilizar el mismo nombre para un método, si cambio el número y tipo de sus argumentos.

La sobrecarga que métodos puede dar lugar a llamadas ambiguas a métodos si Java hace promoción de tipos.

La sobrecarga es una herramienta de la que no debo abusar en mi código.