Anda di halaman 1dari 32

Programao Orientada a Objetos

Aula 11 Manipulao de Referncias, Polimorfismo e Ligao Dinmica

Rafael Braga

Manipulando Referncias
De maneira geral, o tratamento dado em Java para converses de tipo para referncias a objetos anlogo ao que acontece nas converses de tipos primitivos. Converses de tipo (classe) para referncias a objetos podem ocorrer:
implicitamente, em atribuies e passagem de parmetros, ou atravs de casting explcito.

Converses de tipos mais especficos para tipos mais gerais (upcasting) so permitidas. O contrrio, converses de tipos mais gerais para tipos mais especficos (downcasting) exigem casting explcito. Isto vale para a hierarquia completa de herana, incluindo classes e interfaces.
2

Manipulando Referncias
Regras de Converso para Operaes com Variveis de Referncia
1. Operao de Atribuio: TipoDeOrigem origRef; TipoDeDestino destRef = origRef; 2. Operao de Passagem de Parmetro: TipoDeOrigem origRef; enviarParam( origRef ); ... void enviarParam( TipoDeDestino destRef ) { ... }
3

Passagem de Parmetros
Como j foi visto em sees anteriores, a passagem de parmetros de tipos primitivos em Java feita por valor, ou seja, uma cpia do valor original feita. Isso significa que modificaes no parmetro formal no so refletidas no parmetro real. Para arrays, uma cpia da referncia para o array passada.

Para objetos, uma cpia da referncia ao objeto passada, e no uma cpia do objeto.

Passagem de Parmetros com Arrays


Para arrays, uma cpia da referncia para o array passada, assim, as mudanas no seus elementos dentro de um mtodo, se refletem no lugar onde o mtodo foi chamado.
public static void somar(int[] x) { x[2] = x[1] + x[0]; } public static void main (String args[]) { int[] a = new int[3]; a[0] = 1; a[1] = 10; a[2] = 20; antes >20 System.out.println(antes >+ a[2]); somar(a); System.out.println(depois >+ a[2]); depois >11 }
5

Passagem de Parmetros com Arrays


Graficamente...
public static void somar(int[] x) { x[2] = x[1] + x[0]; } ... somar(a);
a x 1 10 20

Passagem de Parmetros com Referncias


Relembrando funcionamento das referncias...
Data hoje; hoje = new Data(); hoje.setDia(11); hoje.setMes(02); hoje.setAno(2004); Data outroDia = hoje; outroDia.setMes(05);
0x852ef8b hoje dia = 11; mes = 05; ano = 2004;

outroDia

referncias

objeto

Passagem de Parmetros com Referncias


Esse fenmeno conhecido como aliasing. Apesar da passagem por parmetros em Java ser por valor, pode-se ter aliasing quando um objeto passado como parmetro, assim como acontece na atribuio de referncias. sempre a referncia (ponteiro) de um objeto que passada como parmetro e no o objeto em si. O parmetro formal passa a ser uma referncia para a mesma instncia do objeto passado, logo, qualquer mudana nos valores do objeto se reflete no lugar onde o mtodo foi chamado.
8

Passagem de Parmetros com Referncias


Exemplo
public static void main( String args[] ) { Data hoje; hoje = new Data(); funcao(hoje); System.out.println( hoje.getMes() ); // 10 } static void funcao( Data umaData ) { umaData.setMes( 10 ); } 0x852ef8b
hoje dia = 0; mes = 10; ano = 0;

umaData
9

Passagem de Parmetros com Referncias


Perceba que os valores dos campos do objeto podem ser alterados dentro do mtodo chamado, porm, mudanas na prpria referncia dentro do mtodo no afetam a referncia externa.
public static void main( String args[] ) { Data hoje; hoje = new Data(); funcao(hoje); System.out.println( hoje.getMes() ); } void funcao( Data umaData ) { umaData.setMes( 10 ); umaData = new Data(); umaData.setDia( 22 ); }
10

Passagem de Parmetros com Referncias


Graficamente...
0x852ef8b dia = 0; mes = 10; ano = 0; hoje

umaData

0x1402bc84
dia = 22; mes = 0; ano = 0;

11

Manipulando Referncias
Casting de Referncias
Object

Upcasting Casting implcito

Estundante

Ex: EstudanteMonitor em = new EstudanteMonitor(); Estudante e = em;

EstudanteMonitor

12

Manipulando Referncias
Exemplos
public class Programa { EstudanteMonitor em = new EstudanteMonitor(); // situao 1 Estudante e = em; // situao 2 Origem Turma t = new Turma(); t.matricular( em ); Destino } public class Turma { ... public void matricular( Estudante e ) {...} ... }
13

Operador instanceof
O operador binrio instanceof tem a seguinte sintaxe:
variavelDeReferencia instanceof TipoDeDestino

O operador instanceof retorna true se o objeto denotado pela variavelDeReferencia, em tempo de execuo
uma instncia da classe TipoDeDestino ou uma instncia de uma subclasse dela.

Perceba que esse teste feito em tempo de execuo.


14

Operador instanceof
Em tempo de compilao, porm, verificado se o tipo da variavelDeReferencia e o TipoDeDestino esto no mesmo ramo da hierarquia de classes. Do contrrio, acontecer um erro de compilao.
A B
c

C E

C c c c c c c

c = new C(); instanceof C instanceof B instanceof A instanceof E instanceof D instanceof Object

true true true false ERRO COMP. true


15

Casting de Referncias
Para fazer casting (converso) da variavelDeReferencia do TipoDeOrigem para o TipoDeDestino, usa-se a seguinte sintaxe:
( TipoDeDestino ) variavelDeReferencia

O casting acima possvel se o objeto denotado pela variavelDeReferencia, em tempo de execuo :


uma instncia da classe TipoDeDestino, ou uma instncia de uma subclasse dela.
16

Casting de Referncias
Quando usar o casting:
public class Turma { ... public Estudante obterEstudante(int mat) {...} } ... EstudanteMonitor em; em = new EstudanteMonitor(111, Pedro, M); Turma t = new Turma() t.matricular( em ); EstudanteMonitor em2 = t.obterEstudante( 111 ); ERRO DE COMPILAO, pois o mtodo obterEstudante() retorna um Estudante e no um EstudanteMonitor.
17

Casting de Referncias
Soluo casting:
public class Turma { ... public Estudante obterEstudante(int mat) {...} } ... EstudanteMonitor em; em = new EstudanteMonitor(111, Pedro, M); Turma t = new Turma() t.matricular( em ); EstudanteMonitor em2 = ((EstudanteMonitor)t.obterEstudante( 111 )); necessrio dizer ao compilador que o mtodo obterEstudante() vai retornar em tempo de execuo, nesse caso, um objeto da subclasse EstudanteMonitor.
18

Casting de Referncias
Quando usar o casting:
... EstudanteMonitor em = new EstudanteMonitor(); Turma t = new Turma() t.matricular( em );

Estudante e = t.obterEstudante( 111 );


e.tirarDuvidas(); ...

ERRO DE COMPILAO, pois a classe Estudante no possui um mtodo chamado tirarDuvidas().

19

Casting de Referncias
Soluo casting:
... EstudanteMonitor em = new EstudanteMonitor(); Turma t = new Turma() t.matricular( em );

Estudante e = t.obterEstudante( 111 );


((EstudanteMonitor) e ).tirarDuvidas(); ... necessrio dizer ao compilador que a referncia e denotar, em tempo de execuo, um objeto que possui um mtodo chamado tirarDuvidas().

20

Casting de Referncias
Object

Upcasting

Downcasting
Estudante

Casting implcito

necessrio fazer o casting explcito

Ex: EstudanteMonitor em = new EstudanteMonitor (); Estudante e = em;

EstudanteMonitor

Ex: Estudante e = new EstudanteMonitor(); EstudanteMonitor em = (EstudanteMonitor)e;

21

Casting e instanceof
Escrevendo cdigo seguro: combinando Casting e instanceof
... EstudanteMonitor em = new EstudanteMonitor(); Turma t = new Turma() t.matricular( em ); Estudante e = t.obterEstudante( 111 ); if ( e instanceof EstudanteMonitor ) { ( (EstudanteMonitor) e ).tirarDuvidas(); } ...

22

Casting e instanceof
Tanto o casting quanto o operador instanceof requerem verificao:
em tempo de compilao, que avalia somente as referncias, e em tempo de execuo, que avalia o objeto propriamente dito.

Ateno para a situao abaixo:


// o trecho abaixo passa na compilao, // mas vai gerar erro de execuo Estudante e = new Estudante(); EstudanteMonitor em = (EstudanteMonitor)e;
O objeto referenciado por e , de fato, um Estudante, e no um EstudanteMonitor.
23

Casting Usando Mtodos


Comportamento dos mtodos com Casting
class Estudante { public void exibir() { ... System.out.println("metodo exibir de Estudante"); } public double lerNota(int prova) { System.out.println("metodo lerNota de Estudante"); return notas[prova-1]; }...} class EstudanteMonitor extends Estudante { public void exibir() { System.out.println("metodo exibir de EstudanteMonitor"); } public void tirarDuvidas() { System.out.println("metodo tirarDuvidas de EstudanteMonitor"); }...}

24

Casting Usando Mtodos


Comportamento dos mtodos com Casting
public class Programa { public static void main( String args[] ) { EstudanteMonitor em = new EstudanteMonitor(); em.exibir(); // executa o exibir() redefinido em // EstudanteMonitor em.lerNota(1); // executa o lerNota() de Estudante em.tirarDuvidas(); // executa o tirarDuvidas() de // EstudanteMonitor Estudante e = em; e.exibir(); // executa o exibir() redefinido em // EstudanteMonitor // e.tirarDuvidas(); // no existe tirarDuvidas() na // classe Estudante -> ERRO!!! ((EstudanteMonitor)e).tirarDuvidas(); // Ok ((Estudante)e).exibir(); // executa o exibir() // do objeto, portanto, 25 // de EstudanteMonitor

Qual objeto uma referncia realmente denotar em tempo de execuo nem sempre se pode determinar em tempo de compilao. Polimorfismo a capacidade de uma referncia denotar diferentes objetos na hierarquia de herana em diferentes momentos durante a execuo. Tal referncia uma referncia de supertipo. Quando um mtodo invocado usando uma referncia, a definio do mtodo que ser realmente executada determinada:
pela classe denotada pela referncia em tempo de execuo, e pela assinatura do mtodo.

Polimorfismo

26

Polimorfismo
Entendendo o Polimorfismo...
(1) (2) (3) (4) (5) EstudanteMonitor em = new EstudanteMonitor(); Estudante e = em; e.atribuirNota(1, 7.5); e = new EstudanteEstagiario(); e.atribuirNota(1, 8.5);
e (2) Estudante

(4)

(1)

em EstudanteMonitor EstudanteEstagiario

27

Polimorfismo
Usando o Polimorfismo...
public class Turma { ... public Estudante obterEstudante(int mat) {...} public void matricular (Estudante e) {...} } ... EstudanteMonitor em; em = new EstudanteMonitor(111, Pedro, M); Turma t = new Turma() t.matricular( em ); EstudanteMonitor em2 = ((EstudanteMonitor)t.obterEstudante( 111 ));

28

Ligao Dinmica
Numa hierarquia de herana de classes, dois mtodos podem ter o mesmo nome e tipo: Definio e redefinio, qual usar? O cdigo escolhido dinamicamente (em tempo de execuo), no estaticamente (em tempo de compilao). Escolha feita com base na classe do objeto associado varivel destino do mtodo. O mecanismo de ligao dinmica (dynamic binding) responsvel por associar uma solicitao (de um mtodo) a um objeto em tempo de execuo.
29

Ligao Dinmica
Observando o emprego do Polimorfismo e da Ligao Dinmica
public class Programa { public static void main( String args[] ) { Estudante e = new Estudante(Pedro); e.exibir(); // executa o exibir() de Estudante e = new EstudanteMonitor(Maria); e.exibir(); // executa o exibir() redefinido em // EstudanteMonitor e = new EstudanteEstagiario(Fernanda); e.exibir(); // executa o exibir() redefinido em // EstudanteEstagiario } }
30

Questionrio
1. O que upcasting e downcasting? 2. Em que situao ou situaes necessrio fazer casting explicto? 3. Em que situao ou situaes no necessrio fazer casting explicto? 4. Quando o operador instanceof retorna verdadeiro? 5. Que validao feita em tempo de compilao quando se usa o operador instanceof? 6. Que validao feita em tempo de execuo quando se usa o operador instanceof? 7. Qual a relao do casting com o operador instanceof? 8. Por que converses usando casting so ditas inseguras? 9. O que polimorfismo? 10. Na herana de classes, quando h redefinio de mtodos, o que se pode dizer sobre a execuo do mtodo? 11. Explique o mecanismo de ligao dinmica.
31

Prtica de Laboratrio
1. Implementar o programa do slide 27 para testar o emprego do casting. 2. Implementar o programa do slide 33 para testar o emprego do polimorfismo e da ligao dinmica. 3. Criar uma classe chamada Apresentador que possui um nico mtodo chamado apresentar(Estudante e), que recebe como argumento um Estudante e exibe seus dados, ou seja, chama o mtodo exibir do objeto passado. 4. Codifique um programa para criar um apresentador e trs estudantes (comum, monitor e estagirio) e pass-los ao apresentador para exibir seus dados. Observe o emprego do polimorfismo e da ligao dinmica.
32

Anda mungkin juga menyukai