Tutorial Java Básico Polimorfismo


El polimorfismo significa muchas formas, por esto debemos recordar que cualquier objeto en Java puede pasar la regla ES-UN con más de una clase (Para más información de esta regla ver el post Tutorial Java Básico Herencia). Esto significa que un objeto puede ser de más de un tipo, veamos un ejemplo:

class Animal {
}
class Dog extends Animal {
}

En este ejemplo tenemos dos clases Animal y Perro, de tal modo que si creamos un objeto se puede decir lo siguiente basado en la regla ES-UN:

  • Un Perro es un Perro
  • Un Perro es un Animal
  • Un Perro es un Objeto
  • Un Animal es un Objeto
  • Un Objeto es un Objeto

Entonces, ¿Cómo se ve esto utilizando Java ?

	Dog d = new Dog();        //Un Perro es un Perro
	Animal a = new Dog();     // Un Perro es un Animal
	Object o = new Dog();     //Un Perro es un Objeto

	Object oa = new Animal(); //Un Animal es un Objeto
	Object od = new Dog();    //Un Objeto es un Objeto

Viendo esto, podemos decir que siempre existe polimorfismo ya que todas las clases heredan de object y pueden ser tratados como por su tipo y como por el tipo Object.

Referencias

Como se puede observar las referencias son un punto clave cuando se habla de polimorfismo, ya que son estas las que pueden apuntar a multiples tipos de objetos, por esto mencionemos algunas reglas que se tienen en el uso de referencias:

  1. Una referencia apunta a un objeto en memoria
Dog d = new Dog();

La referencia de tipo Dog es “d” y apunta a un objeto en memoria de tipo Dog

  1. Una referencia puede ser re asignada a un objeto diferente en memoria (a menos que este declarada como final)
Dog d = new Dog();
d = new Dog();

La referencia de tipo Dog es “d” y apunta inicialmente a un objeto de tipo Dog, después, la misma referencia apunta a un nuevo objeto de tipo Dog.

  1. La referencia que se utiliza define los métodos del objeto que pueden ser invocados
class Animal {
	void born() {
	}
}

class Dog extends Animal {
	void bark() {
	}
}

En este ejemplo se tiene la clase Animal que cuenta con el método nacer, y la clase Perro que cuenta con el método ladrar, ahora veamos el siguiente método main:

Captura de pantalla 2017-06-28 a las 5.44.06 p.m.

Como se puede observar en la imagen se creó un objeto de tipo perro y se tienen los dos métodos disponibles, ladrar y nacer, ahora veamos lo siguiente:

Captura de pantalla 2017-06-28 a las 5.45.55 p.m.

Si creamos el mismo objeto perro pero ahora se utiliza una referencia de tipo Animal solo se tendrá disponible el método nacer. Con esto se demuestra que la referencia define los métodos disponibles.

  1. Una referencia puede apuntar a un objeto de su tipo o sub tipo
Animal d = new Animal();
d = new Dog();

En este ejemplo se puede observar con se crea una referencia de tipo Animal apuntando a un objeto de tipo animal y después se apunta a un objeto del tipo Perro el cuál hereda de Animal.

  1. Es posible crear una referencia utilizando una clase o una interfaz
interface Funny {
	void smile();
}

class Animal {
	void born() {
	}
}

class Dog extends Animal implements Funny {
	void bark() {
	}
	@Override
	public void smile() {
	}
}

Si se cuenta con las clases e interfaces mencionadas es posible hacer lo siguiente:

Funny f = new Dog();

Pero solo estará disponible para su uso el método smile().

Caso de ejemplo

Una vez que ya se entiende el concepto de polimorfismo y se entiende como utilizar las referencias de distintas formas, la pregunta es ¿Cómo lo utilizo en mi aplicación?, veamos un ejemplo:

interface Figure {
	double calculateArea();
}

class Circle implements Figure {
	private double radius;

	public Circle(double radius) {
		this.radius = radius;
	}

	@Override
	public double calculateArea() {
		return Math.PI * (Math.pow(radius, 2));
	}

}

class Square implements Figure {
	private double side;

	public Square(double side) {
		this.side = side;
	}

	@Override
	public double calculateArea() {
		return side * side;
	}

}

public class Triangle implements Figure {
	private double base;
	private double height;

	public Triangle(double base, double height) {
		this.base = base;
		this.height = height;
	}

	@Override
	public double calculateArea() {
		return (base * height) / 2;
	}

Como se puede observar se cuenta con 3 clases y una interfaz Figura, Cuadrado, Triángulo y Circulo. La interfaz Figura define el método  public double calculateArea() y las 3 figuras implementan ese método de forma diferente.  Ahora imaginemos que deseamos crear una clase que calcule el area de multiples figuras, en este momento solo son 3 pero se espera que podamos tener 300 figuras más en la aplicación.

Entonces la pregunta sería,  ¿tendremos que crear 300 métodos para las 300 figuras? La respuesta es no, a continuación se muestra como se resolvería el problema haciendo uso del polimorfismo:

public double calcAreas(Figure []figures){
	double area=0;
	for (Figure figure : figures) {
		area=figure.calculateArea();
	}
	return area;
}

Como se puede observar el método calcAreas no sabe que figuras existen, este solo hace uso de una arreglo de Figuras y con esto calcula todas las areas que requiere, entonces no importa cuantos tipos de Figuras creemos este método será capaz de calcular el área de todas ellas.

Los libros recomendados para este tema son:

Autor: Alejandro Agapito Bautista

Twitter: @raidentrance

Contacto:raidentrance@gmail.com

Anuncios

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 )

Google+ photo

Estás comentando usando tu cuenta de Google+. 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 )

Conectando a %s