Buscar

Polimorfismo e Reutilização de Código

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 5 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

PONTIFÍCIA UNIVERSIDADE CATÓLICA DE MINAS GERAIS
Unidade de Contagem
Disciplina Curso Turno Período
Linguagens de Programação Sistemas de Informação Noturno 3◦
Professor
Camillo J. S. Oliveira
Polimorfismo (parte 2)
Na prática anterior, viu-se como fazer para ocultar métodos herdados e produzir um código polimórfico.
Agora será ilustrado como o polimorfismo pode ser explorado para produzir um código mais robusto, mais
genérico e obter uma maior reutilização de código.
Observe o código a seguir:
import java . app le t . Applet ;
import java . awt . ∗ ;
class Quadrado {
private int x , y , lado ;
private Color cor ;
public Quadrado ( int px , int py , int l ) {
x = px ;
y = py ;
lado = l ;
}
public void setCor ( Color c ) {
cor = c ;
}
public void desenha ( Graphics g ) {
Color velhaCor = g . getColor ( ) ;
g . s e tCo lo r ( cor ) ;
g . drawRect (x , y , lado , lado ) ;
g . s e tCo lo r ( velhaCor ) ;
}
}
class Circu lo {
private int x , y , lado ;
private Color cor ;
public Circu lo ( int px , int py , int l ) {
x = px ;
y = py ;
lado = l ;
cor = Color . b lack ;
}
public void setCor ( Color c ) {
cor = c ;
}
public void desenha ( Graphics g ) {
Color velhaCor = g . getColor ( ) ;
g . s e tCo lo r ( cor ) ;
g . drawOval (x , y , lado , lado ) ;
g . s e tCo lo r ( velhaCor ) ;
}
}
import java . app le t . Applet ;
import java . awt . Graphics ;
import java . awt . Color ;
class ListaDeFiguras {
private Quadrado vetQ [ ] ;
private Circu lo vetC [ ] ;
private int tmax , cq , cc ;
public ListaDeFiguras ( int t ) {
vetQ = new Quadrado [ t ] ;
vetC = new Circu lo [ t ] ;
tmax = t ;
cq = 0 ;
cc = 0 ;
}
public void i n s e r e (Quadrado q ) {
i f ( cq == tmax)
return ;
vetQ [ cq ] = q ;
cq++;
}
public void i n s e r e ( C i r cu lo c ) {
i f ( cc == tmax)
return ;
vetC [ cc ] = c ;
cc++;
}
public void desenha ( Graphics g ){
for ( int i = 0 ; i < cq ; i++)
vetQ [ i ] . desenha ( g ) ;
for ( int i = 0 ; i < cc ; i++)
vetC [ i ] . desenha ( g ) ;
}
}
import java . app le t . Applet ;
import java . awt . Graphics ;
import java . awt . Color ;
public class Pol imorf i smo extends Applet {
ListaDeFiguras l f ;
public void i n i t ( ) {
l f = new ListaDeFiguras ( 1 0 ) ;
l f . i n s e r e (new Quadrado ( 0 , 0 , 3 0 ) ) ;
l f . i n s e r e (new Quadrado (100 , 100 , 80 ) ) ;
l f . i n s e r e (new Circu lo ( 2 0 , 4 0 , 3 4 ) ) ;
}
public void paint ( Graphics g ) {
l f . desenha ( g ) ;
}
}
Para executar o código acima utilize o eclipse e pressione o mouse em Run as applet... ou crie um
arquivo HTML com o seguinte código:
<BODY>
<APPLET CODE=Polimorfismo.class WIDTH=200 HEIGHT=200></APPLET>
</BODY>
o código acima é formado de basicamente quatro classes. As classes Quadrado e Circulo são praticamente
idênticas e representam duas figuras geométricas. A Classe ListaDeFiguras representa um repositório de
figuras. Nesta classe são gerenciados os objetos que são adicionados ao programa. Ela também possui um
método desenha que desenha todos os objetos geográficos construídos. Finalmente, a classe Polimorfismo
representa a nossa aplicação gráfica. Ela é construída na forma de um Applet, o que permite que o código
seja executado dentro de um navegador Web.
Antes de seguir para a próxima seção, pense nas seguintes questões:
1. É possível se utilizar herança no código acima?
2. Quais as vantagens poderiam ser obtidas com herança?
Herança e polimorfismo atuando juntos para reuso de código
class Figura {
protected int x , y , lado ;
protected Color cor ;
public Figura ( int px , int py , int l ) {
x = px ;
y = py ;
lado = l ;
cor = Color . b lack ;
}
public void setCor ( Color c ) {
cor = c ;
}
public void desenha ( Graphics g ) {
}
}
class Quadrado extends Figura {
public Quadrado ( int px , int py , int l ) {
super (px , py , l ) ;
}
public void desenha ( Graphics g ) {
Color velhaCor = g . getColor ( ) ;
g . s e tCo lo r ( cor ) ;
g . drawRect (x , y , lado , lado ) ;
g . s e tCo lo r ( velhaCor ) ;
}
}
class Circu lo extends Figura {
public Circu lo ( int px , int py , int l ) {
super (px , py , l ) ;
}
public void desenha ( Graphics g ) {
Color velhaCor = g . getColor ( ) ;
g . s e tCo lo r ( cor ) ;
g . drawOval (x , y , lado , lado ) ;
g . s e tCo lo r ( velhaCor ) ;
}
}
No exemplo de código acima criou-se a classe Figura e as classes Quadrado e Circulo passam a ser
sub-classes de Figura. Esta herança permitiu reutilização de código, onde apenas a parte diferente das
classes teve que ser definida nas classes filha. Lembre-se que em uma aplicação mais completa, os métodos
mover, posicionar, dimensionar, entre outros, todos poderiam estar na classe Figura, garantindo uma
grande reutilização de código. Ou seja, a herança tornou possível a eliminação de rotinas redundantes entre
as classes Quadrado e Circulo.
Entretanto, apenas a herança ainda não produz nenhum efeito prático sobre a classe ListaDeFiguras.
Veja a seguir a utilização de polimorfismo na classe ListaDeFiguras e tente compreender como o polimorfismo
permitiu a construção de um código mais genérico baseado na classe Figura.
class ListaDeFiguras {
private Figura vet [ ] ;
private int tmax ;
private int c ;
public ListaDeFiguras ( int t ) {
tmax = t ;
c = 0 ;
vet = new Figura [ t ] ;
}
public void i n s e r e ( Figura f ) {
i f ( c == tmax)
return ;
vet [ c ] = f ;
c++;
}
public void desenha ( Graphics g ) {
for ( int i = 0 ; i < c ; i++)
vet [ i ] . desenha ( g ) ;
}
}
No código fonte da classe acima, o vetor vet[] passou a ser um vetor polimórfico sobre a classe Figura.
O laço da função desenha da classe ListaDeFiguras irá desenhar dinamicamente o objeto que estiver na
memória no momento. Ou seja, se o vetor apontar para um quadrado, será executada a função desenha de
um quadrado. Se for um círculo, será desenhado um círculo.
Quando dispõe-se da referência para a classe “pai” só se pode acessar os métodos previstos na interface
da classe “pai”. Por isso foi necessário criar o método desenha vazio na classe Figura. Porém, durante o
polimorfismo, o Java automaticamente ativa a implementação correspondente no objeto apontado.
Caso o programador precise saber exatamente que objeto está instanciado na memória e está sendo
apontado por uma referência polimórfica, ele pode usar o comando instanceof. O comando instanceof
retorna o nome da classe do objeto (mais baixa na hierarquia de herança). Por exemplo:
i f ( vet [ i ] instanceof Circu lo )
System . out . p r i n t l n ( " Ci rcu lo " ) ;
Classes abstratas
Classes abstratas permitem que se definam métodos sem implementação, que devem ser redefinidos
em classes derivadas. O que define se uma classe é abstrata ou não é a ocorrência de pelo menos um
método abstrato. Classes abstratas não podem ser instanciadas, ou seja, nenhum objeto desta classe pode
ser construído com a cláusula new. As classes derivadas de classes abstratas herdam todos os métodos,
incluindo os abstratos. Um classe abstrata não precisa possuir métodos abstratos. Mas toda classe com
métodos abstratos deve ser declarada como uma classe abstrata. As classes derivadas de classes abstratas
são abstratas até que implementem os métodos abstratos. Observe a classe figura. Ela poderia ser uma
classe abstrata.
abstract class Figura {
protected int x , y , lado ;
protected Color cor ;
public Figura ( int px , int py , int l ) {
x = px ;
y = py ;
lado = l ;
cor = Color . b lack ;
}
public void setCor ( Color c ) {
cor = c ;
}
public abstract void desenha ( Graphics g ) ;
}
Interfaces
Interfaces em Java são como classes onde tudo é abstrato. Interfaces não são estendidas, mas imple-
mentadas pelas classes usando a palavra-chave implements. Define-se a interface de uma classe de objetos,
deixando a implementação a cargo de cada especialização desta classe. Interfaces são usadas para definir
um protocolo de comportamento que pode ser implementado por qualquer classe na hierarquia de classes. É
permitido se criar hierarquia de interfaces.
Definir uma interface é similara definir uma nova classe. Na declaração da interface, declara-se os
atributos tais como nome da interface e se ela herda de outra interface. O corpo da interface contém as
declarações de constantes e dos métodos da interface.
Para que uma classe possa usar uma interface usa-se a palavra-chave implements. Ao contrário de
classes abstratas, uma classe que implementa uma interface provê o código para a implementação de todos
os métodos declarados na interface. Interfaces podem ser declaradas, mas não podem ser instanciadas, assim
como classes abstratas.
Exemplo: Alarmes e Dorminhocos
A classe AlarmClock é um serviço que notifica objetos dorminhocos que um certo tempo passou. Um
objeto dorminhoco deve fazer duas coisas: pedir para o Alarme acordá-lo após certo tempo e implementar o
método wakeUp. Se o AlarmClock tem espaço na lista, ele registra o dorminhoco e começa uma nova tarefa
(thread) para este dorminhoco. Um objeto que quiser usar o AlarmClock deve implementar o método. A
interface Sleeper define o método wakeUp() mas não a implementa. Ela também define constantes úteis. As
classes que implementarem esta interface “herdam” a constante e devem implementar o método wakeUp().
Todo objeto será também um dorminhoco.
Para exemplificar o uso de interfaces veja o código de um relógio que deve ser acordado a cada segundo
para atualizar o display do tempo.
Pegue o código que está disponível no arquivo Alarme.zip e compile.
Porque utilizar interfaces ao invés de classes abstratas?
Uma interface é simplesmente uma coleção de métodos abstratos. Seria a classe abstrata Sleeper equiv-
alente à interface?
Resposta: Não. Se Sleeper fosse classe abstrata apenas objetos que herdassem de Sleeper poderiam
ser utilizados no AlarmClock. Se o relógio for um applet ele deve herdar da classe applet. Como Java não
permite herança múltipla não seria possível tornar o relógio um dorminhoco (Sleeper).
Interfaces provem Herança Múltipla?
Podem ser encarados como um paliativo, mas são coisas diferentes: uma classe herda apenas constantes
de uma interface; uma classe não pode herdar implementações de uma interface. A hierarquia de interfaces
é independente da hierarquia de classes. Classes que implementam a mesma interface podem ou não estar
relacionadas na hierarquia. Java permite herança múltipla de interfaces.
Para que usar Interfaces?
Use interfaces para definir protocolos de comportamento que possam ser implementados em qualquer
lugar na hierarquia de classes. Interfaces são úteis para: capturar similaridades entre classes não relacionadas;
declarar métodos que uma ou mais classes devem inevitavelmente implementar; revelar interfaces sem revelar
os objetos que a implementam (útil na venda de pacotes de componentes).
Exercícios de Hoje
1. Compile e explique cada uma das linhas do exemplo da seção "Herança e polimorfismo"atuando juntos
para reuso de código. Cite em que linhas o polimorfismo está presente. Utilize a classe Figura que seja
abstrata. incremente a classe figura com métodos tais como mover, posicionar, aumentar e diminuir.
crie mais de um construtor com parâmetros.
2. Compile e execute o código disponível no pacote Alarme.zip. Tente explicar a função da interface
Sleeper. Explique como o polimorfismo age sobre a função wakeUp() de Sleeper.
3. Baseado no que foi dito. Dê um exemplo da possível utilização de classes abstratas e interfaces em
Programação Orientada para Objetos.
Entregue apenas as respostas num único documento TXT ou DOC.

Outros materiais