RSS

Orientación a objetos (II)

08 May

Polimorfismo

Hemos hablado anteriormente del polimorfismo cuando hablabamos sobre la herencia. Decíamos que una variable es polimórfica porque puede hacer referencia a objetos de distintas formas.

Y vimos que Java permitía hacer referencia a un objeto con una variable del tipo de una superclase.
Empleado e = new Tecnico();

Usando la variable e podíamos acceder únicamente a las partes del objeto que son componentes de Empleado (la superclase). Esto se debía a que para el compilador la variable e es de tipo Empleado y no Tecnico.

Pero supongamos que ambas clases tienen un método toString().
Sabemos que si declaramos lo siguiente y llamamos a toString()

Empleado e1 = new Empleado();
Tecnico e2 = new Tecnico();

e1.toString();
e2.toString();

e1 llama al método toString() de la clase Empleado y e2 llama al método toString de la clase Tecnico.

¿Pero que ocurre si hacemos esta llamada?

Empleado e3 = new Tecnico();
e3.toString();

Se obtiene el comportamiento asociado al objeto al que hace referencia la variable durante el tiempo de ejecución. El comportamiento no está determinado por el tipo de la variable en el momento de la compilación. Este es un aspecto del polimorfismo que a menudo recibe el nombre de llamada a métodos virtuales.

e3.toString() llama al método del tipo real del objeto, Tecnico.

Colecciones hetereogéneas

Es posible crear colecciones de objetos que son de una misma clase. Estas colecciones se llaman homogéneas. Por ejemplo, cualquier array que construyamos de una clase es una colección homogénea:

Clientes[ ] clientesNuevos = new Clientes[100];
clientesNuevos[0] = new Cliente();
clientesNuevos[1] = new Cliente();
clientesNuevos[2] = new Cliente();

Sin embargo, Java permite crear colecciones compuestas por objetos de distintos tipos. Estas colecciones se llaman hetereogéneas.

Por ejemplo, una colección con objetos de las subclases de Empleado que vimos anteriormente:
Empleado[] empleados = new Empleado[3];
empleados[0] = new Tecnico();
empleados[1] = new Secretario();
empleados[2] = new Contable();

Es incluso posible hacer una colección con objetos de cualquier clase, ya que en Java todos los objetos heredan de Object. Podemos tener una colección como esta:

Object  [] objetos = new Object[5];
objetos[0] = new Empleado();
objetos[1] = new Batman();
objetos[2] = new Libro();
objetos[3] = new String(“Maria”);
objetos[4] = new Bicicleta();

Podríamos recorrer el array y llamar a un método que fuera común, por ejemplo toString().


Sobrecarga de métodos

En algunos casos podemos necesitar definir varios métodos que realicen la misma función pero con diferentes parámetros. Java permite reutilizar un mismo nombre de método para varios métodos si al llamarlos es posible distinguir unos y otros.

Reglas de los métodos sobrecargados:

  • Las listas de argumentos deben ser diferentes. Deben poder determinar sin ambigüedad qué método es el que se quiere llamar.
  • Los tipos de retorno pueden ser diferentes. El tipo de retorno puede ser diferente pero no es suficiente si ésta es la única diferencia.
  • El modificador de acceso puede cambiar.
  • Puede declarar nuevas o más amplias excepciones comprobadas.

Y a tener en cuenta:

  • Un método se puede sobrecargar en la misma clase o en una subclase.


Llamadas a métodos sobrecargados

Cuando llamamos a un método sobrecargado, existe más de un método con el mismo nombre. Decidir qué método es el que se debe llamar se hace en base a los argumentos.

Si tenemos un método sumar(int a, int b), y otro método sumar(double a, double b).
La llamada sumar(10, 7) llama a sumar con argumentos enteros y la llamada sumar(2.7, 2.3) llama a sumar con argumentos double.

¿Pero qué ocurre cuando en lugar de parámetros de tipos primitivos tenemos parámetros de tipos de referencia?

Supongamos estos métodos sobrecargados de la clase Proyecto.

public void añadirPersonal (Empleado e);
public void añadirPersonal (Tecnico t);

Con estas llamadas:
Empleado e = new Empleado();
Tecnico t = new Tecnico();
Empleado tec = new Tecnico();

e.añadirPersonal(e); //Como esperamos e es de tipo Empleado y llama a añadirPersonal(Empleado e)
e.añadirPersonal(t); //Como es de esperar, t es de tipo Tecnico y llama a añadirPersonal(Tecnico t)
e.añadirPersonal(tec); //En este caso tec es una referencia de Empleado pero es en realidad un objeto Tecnico.

En este ultimo caso se llama al método añadirPersonal(Empleado e).

Aunque el objeto en tiempo de ejecución sea un Tecnico, la decisión de a qué método llamar no se hace dinámicamente en tiempo de ejecución, asi que el tipo de referencia determina a qué metodo sobrecargado se llama.

Anuncios
 
1 comentario

Publicado por en 8 mayo, 2011 en Estudio, Tema 2

 

Etiquetas: , , , ,

Una respuesta a “Orientación a objetos (II)

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

 
A %d blogueros les gusta esto: