Upload
dotruc
View
217
Download
0
Embed Size (px)
Citation preview
Polimorfismo
Universidade Federal de UberlândiaFaculdade de Computação
Disciplina – POO1
Prof. Fabiano Dorça
Polimorfismo
● Polimorfismo significa "muitas formas".
● Permite ao desenvolvedor usar o mesmo elemento de formas diferentes.
● Situação na qual um objeto pode responder de maneiras diferentes ao receber uma mensagem.
Polimorfismo
● O polimorfismo pode ocorrer quando:– há sobreposição de métodos da superclasse nas
subclasses.
● Em tempo de execução o polimorfismo ocorre através de ligação dinâmica (dynamic binding).
● O método a ser executado é determinado apenas em tempo de execução (e não em tempo de compilação).
Polimorfismo
● Quando um método é chamado...
– a classe de instanciação do objeto (não a classe de declaração) dita a implementação a ser usada.
Polimorfismo
● A classe de declaração de um objeto é determinada em tempo de compilação.
– O compilador tem acesso a essa informação na própria declaração da referência.
Polimorfismo
● O polimorfismo permite “programar no geral” em vez de “programar no específico”.
● Escrever programas que processam objetos que compartilham a mesma superclasse.
Polimorfismo
● Exemplo: calculo do imposto de funcionários
public abstract class Funcionario{…public abstract double calcSalario();
}
public class Supervisor extends Funcionario{...public double calcSalario(){ return ....}
}
Polimorfismo
public class Vendedor extends Funcionario{...public double calcSalario(){ return ....}
}
public class Gerente extends Funcionario{...public double calcSalario(){ return ....}
}
Polimorfismo
→ Deve ser criado um método na classe FolhaPagamento capaz de calcular o imposto de renda a ser pago pelos funcionários
→ Mas independentemente do tipo de funcionário, a forma de calcular o imposto é o mesmo...
Polimorfismo
public class FolhaPagamento{ … public double calcImpVend(Vendedor v){ return v.calcSalario() * 0.275; } public double calcImpSup(Supervisor s){ return s.calcSalario() * 0.275; } public double calcImpGerente(Gerente g){ return g.calcSalario() * 0.275; }}
Polimorfismo
● Considerando o polimorfismo, e a máxima “programe para o geral, e não para o específico”...
→ poderíamos criar um método geral para cálculo do imposto de qualquer tipo de funcionário.
Polimorfismo
public class FolhaPagamento{ … public double calcImposto(Funcionario f){ return f.calcSalario() * 0.275; }
Chamada polimórfica ao método calcImposto()
Polimorfismo
public abstract class Forma{ public abstract float calcularArea(); public abstract float calcularPerimetro();}
Polimorfismo
public class Circulo extends Forma{ private float raio; … public float calcularArea(){ return Math.PI * raio * raio; } public float calcularPerimetro(){ return 2 * Math.PI * raio; }}
Polimorfismo
public class Retangulo extends Forma{ private float altura, base; … public float calcularArea(){ return altura * base; } public float calcularPerimetro(){ return 2 * (altura+base); }}
Polimorfismo
● Podemos atribuir a “f ” objetos de qualquer subclasse de Forma:
Forma f;f = new Circulo();f.calcularArea();…f = new Retangulo();…f.calcularArea();f = new Quadrado();
Polimorfismo
● Desta forma, poderíamos pensar em um método genérico para desenhar formas:
public abstract class Desenho{ public static void desenhar(Forma f) { System.out.println(f.getClass().getName()); System.out.println(“Área: ”+f.calcularArea()); }}
● Em tempo de execução, qual será a saída?
Polimorfismo
● Como o método desenhar recebe uma forma, poderíamos fazer:
Circulo c = new Circulo();…Retangulo r = new Retangulo();…Desenho.desenhar(c);Desenho.desenhar(r);...
Polimorfismo
● Exemplo: Implementação de um jogo
public class Jogador{
public void atirar(Revolver r){ r.atirar(); }
public void explodir(Bomba b){ b.explodir(); }}
Polimorfismo
public class Revolver{ public void atirar(){ System.out.println(“atirando...”); }}
public class Bomba{ public void explodir(){ System.out.println(“explodindo...”); }}
Polimorfismo
● Problemas com este projeto?
– Sempre que novas armas forem introduzidas no jogo, a classe jogador sofrerá alterações...
– Difícil manutenção– Possível replicação de código
PolimorfismoIntrodução de novas armas implicam em alterações na classe Jogador...
public class Jogador{ ... public void atirar(Revolver r){ r.atirar(); } public void explodir(Bomba b){ b.explodir(); } public void lançar(Dardos d){ d.lançar(); }}
Polimorfismo
● Solução: – criação de uma abstração para armas através do
uso de herança.– Uso de polimorfismo em jogador.
Polimorfismo
public abstract class Arma{ public abstract void usar();}
public class Revolver extends Arma{ public void usar(){ System.out.println(“atirando...”); }}
public class Bomba extends Arma{ public void usar(){ System.out.println(“explodindo...”); }}
Polimorfismo
● Através do polimorfismo poderia ocorrer:
Jogador j = new Jogador();…Revolver r = new Revolver();Bomba b = new Bomba();…j.usarArma(r);...j.usarArma(b);
Polimorfismo
● Polimorfismo em ArrayLists
Um ArrayList para armazenar circulos, retangulos e quadrados:
ArrayList<Forma> a = new ArrayList<Forma>();
Polimorfismo
Métodos que recebem diversos tipos de ArrayList
Exemplo:
public void desenhar(ArrayList<? extends Forma>){
}
→ Neste caso, o método pode receber como entrada um ArrayList de qualquer coisa que estenda forma, por exemplo, ArrayList<Circulo> ; ArrayList<Retangulo> ; ArrayList<Quadrado>
Polimorfismo
● Qual a diferença?
public void desenhar(ArrayList<? extends Forma>){
}
public void desenhar(ArrayList<Forma>){
}
Polimorfismo
● Com o polimorfismo, podemos projetar sistemas facilmente extensíveis.
– Novas funcionalidades são adicionadas com pouca ou nenhuma modificação a partes gerais do programa.
– A adição de novas classes não tem impacto no código que já está pronto.
– Desta forma, todo código deve ser escrito para uma abstração e não para uma classe concreta.
Polimorfismo
● Exercícios:
– Desenhe o diagrama de classes da primeira implementação do jogo.
– Desenhe o diagrama de classes da segunda implementação do jogo e compare-os.
– Insira novas armas na implementação polimórfica do jogo, observando a facilidade de extensão da aplicação.
– Crie uma classe FabricaInimigo cujo método fabricar() deve instanciar e retornar aleatóriamente um sub-tipo de inimigo a cada chamada.
Referências
BOOCH, G. Object-Oriented Analysis and Design with Applications, 3a Edição. Addison-Wesley, 2007.BOOCH, G., RUMBAUGH, J., JACOBSON, I. UML, Guia do Usuário. Rio de Janeiro: Campus, 2000.DEITEL, H. M.; DEITEL P. J. Java: Como Programar, 6a. Edição. Pearson, 2005. (Livro Texto)FOWLER, M. UML Essencial, 2a Edição. Bookmann, 2000.HORSTMANN, C.; CORNELL, G. Core Java 2 - Fundamentals, 7a. Edição. Prentice Hall, 2004.LARMAN, C. Utilizando UML e Padrões: Uma Introdução à Análise e ao Projeto Orientado a Objetos. PortoAlegre: Bookmann, 2001.RUMBAUGH, J.; BLAHA, M. Modelagem e Projetos Baseados em Objetos com UML 2, 1a Edição. EditoraCampus, 2006