interface Imposto{
public double calcula(double valor);
}
class ICMS implements Imposto{
public double calcula(double valor){
return valor*1.05;
}
}
class ISS implements Imposto{
public double calcula(double valor){
return valor*1.10;
}
}
class CalculadoraDeImpostos{
public double calculaImpostoSobre(double valor,Imposto imposto){
return imposto.calcula(valor);
}
}
public class TestaImpostos{
public static void main(String [] args){
Imposto icms = new ICMS();
ISS iss = new ISS();
CalculadoraDeImpostos calculadora = new CalculadoraDeImpostos();
double valorCompra = 100;
valorCompra = calculadora.calculaImpostoSobre(valorCompra,icms);
System.out.println("valor com icms :" + valorCompra );
valorCompra = calculadora.calculaImpostoSobre(valorCompra,iss);
System.out.println("valor com iss :" + valorCompra );
}
}
Poliformismo é a capacidade de referenciar objetos de uma classe de outras formas. No exemplo a seguir, é definido a interface Imposto ,ICMS e ISS que são classes que implementam , e uma classe CalculadoraDeImpostos para a contabilização dos impostos através do método calculaImpostoSobre(valor,imposto) que espera receber um valor e o imposto a ser aplicado.
Na classe de testes é criado um objeto para cada tipo de imposto (icms,iss), mas perceba que referencio esses objetos de formas diferentes. O objeto icms é referenciado pelo o tipo definido na interface(Imposto), enquanto que o objeto iss é referenciado pela a sua classe concreta(ISS).
Qual é a vantagem disso? Perceba que o método calculaImpostoSobre espera um Imposto , e as classes ICMS e ISS são Impostos, então posso passar qualquer classe que seja subtipo de Imposto, tanto as existentes , como as futuras classes que possam existir sem nenhuma alteração no método calculaImpostoSobre.