domingo, 25 de junio de 2017

Un Ejemplo de Polimorfismo en Java


La idea es mostrar un ejemplo de polimorfismo para los que comienzan a programar en el paradigma orientado a objetos.

La idea es que una empresa tiene un conjunto de bienes los cuales tienen un valor y a la vez algunos bienes pueden ser amortizados (La amortización es un término económico y contable, referido al proceso de distribución de gasto en el tiempo de un valor duradero. Adicionalmente se utiliza como sinónimo de depreciación en cualquiera de sus métodos.)

Los bienes se clasifican en inmuebles, muebles y rodados. A la vez los inmuebles no pierden el valor en el tiempo (es decir no son amortizables) . El software debe proveer una forma de saber el valor de todos los bienes y calcular su amortización.

Para resolver este problema vamos a definir 2 interfaces una que describa la característica que tienen los bienes de saber su valor y otra que describa la característica de calcular la amortización.

public interface Valorizable {

public Double getValor();

}


public interface Amortizable {

public Double calcularAmortizacion();

}

Programemos los bienes, empesamos con el mueble que para el ejemplo le puse Edificio:

import java.util.Calendar;
import java.util.Date;

public class Edificio implements Valorizable, Amortizable {

private Double valor;
private Date fechaDeCreacion;

public Edificio(Double valorInicial, Date fechaDeCreacion) {
this.valor = valorInicial;
this.fechaDeCreacion = fechaDeCreacion;
}

@Override
public Double calcularAmortizacion() {
Calendar cal = Calendar.getInstance();
int actualYear =cal.get(Calendar.YEAR);
cal.setTime(fechaDeCreacion);
int year =cal.get(Calendar.YEAR);
int diferencia = actualYear - year;
Double amortizacion = (diferencia * valor) / 300;
this.valor = this.valor - amortizacion;
return amortizacion;
}

@Override
public Double getValor() {
return this.valor;
}

@Override
public String toString() {
return "mueble " + this.valor;
}

}

Seguimos con el rodado:

public class Rodado implements Amortizable, Valorizable{

private static final Double VALOR_AMORTIZACION = 0.2;
private Double valor;
private Integer kms;

public Rodado(Double valorInicial, Integer kms) {
this.valor = valorInicial;
this.kms = kms;
}

public Double getValor() {
return valor;
}

public Double calcularAmortizacion() {
Double amotizacion = 0.0;
if (valor > 0.0) {
amotizacion = (VALOR_AMORTIZACION * kms.doubleValue())/100;
valor = valor - amotizacion;
}
return amotizacion;
}

@Override
public String toString() {
return "rodado " + this.valor;
}

}

Y por ultimo programemos el terreno: 


public class Terreno implements Valorizable {

private Double valor= 0.0;
private String direccion = "";
public Terreno(Double valor, String direccion) {
this.valor = valor;
this.direccion = direccion;
}

@Override
public Double getValor() {
return valor;
}

@Override
public String toString() {
return this.direccion;
}
}

De esta manera podemos tratar a todos los objetos amortizables como si fueran del mismo tipo y a todos los valorables como si fueran del mismo tipo, sin importarnos como calculan el valor o la amortización. 

Veamos el main: 

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

public class Main {


public static void main(String[] args) {
// Construyo los Objetos
Calendar cal = Calendar.getInstance();
cal.set(1990, 02, 02);
Edificio unEdificio  = new Edificio(150000.00, cal.getTime());
Rodado unRodado = new Rodado(12000.00, 1000);
Terreno unTerreno = new Terreno(600000.00, "Los colibies 234");
List<Amortizable> list = new ArrayList<>();
list.add(unEdificio);
list.add(unRodado);
//list.add(unTerreno); No es posible agregar un terreno porque no es Amortizable
System.out.println();
System.out.println("Calcular Amortizacion");
for (Amortizable amortizar : list) {
System.out.println(amortizar.calcularAmortizacion());
}
List<Valorizable> list2 = new ArrayList<>();
list2.add(unEdificio);
list2.add(unRodado);
list2.add(unTerreno);
System.out.println();
System.out.println("Imprimir el valor");
for (Valorizable valorizar : list2) {
System.out.println(valorizar.getValor());
}

// En Java es común el uso de polimorfismo, veamos un ejemplo: 
List<Object> list3 = new ArrayList<>();
list3.add(unEdificio);
list3.add(unRodado);
list3.add(unTerreno);
list3.add("Hola!");
System.out.println();
System.out.println("Hacer to String");
for (Object object : list3) {
System.out.println(object.toString()); //toString es llamado de forma polimorfica.
}


}

}

Recuerden que el polimorfismo se refiere a la propiedad por la que es posible enviar mensajes sintácticamente iguales a objetos de tipos distintos. El único requisito que deben cumplir los objetos que se utilizan de manera polimórfica es saber responder al mensaje que se les envía.

Espero que les sirva!!