Você está na página 1de 33

INF1337 LINGUAGEM DE PROGRAMAO ORIENTADA A OBJETOS

Departamento de Informtica PUC-Rio Andrew Diniz da Cosa andrew@les.inf.puc-rio.br

Programa Captulo 5
Converso de Tipos Polimorfismo O Modificador final O Modificador abstract

LES/PUC-Rio

Programa Captulo 5
Converso de Tipos Polimorfismo O Modificador final O Modificador abstract Exerccios IR e Lista Encadeada

LES/PUC-Rio

Diagrama de Classes

Converso (1)
Para estudarmos a compatibilidade entre classes, subclasses e superclasses, tomemos o trecho de cdigo a seguir:
Public class Ex { public static void main(String[] args) { Poligono p1=new Quadrado(); Retangulo r1=new Quadrado(); } }

Neste exemplo podemos notar que a varivel p1, do tipo Poligono, ir guardar uma referncia para um objeto do tipo Quadrado aps a execuo de new Quadrado().

LES/PUC-Rio

Converso (2)
Isso pode ser feito porque todo quadrado um retngulo; isto , todas as propriedades de um retngulo so vlidas para um quadrado; O mesmo se aplica a um polgono: todas as propriedades de um polgono so vlidas para um quadrado; Isso nos permite referenciar um objeto de uma classe a partir de uma referncia para um ancestral da classe em questo;

LES/PUC-Rio

Converso Explcita
Assim como podemos converter um double em um int, embora possa haver perda de informao, ns tambm podemos converter um objeto de uma superclasse em um objeto de uma subclasse; Entretanto, isso deve ser feito de maneira explcita, colocando nome do tipo entre parnteses, e imediatamente antes do objeto que ser convertido.

public static void main(String[] args) { Poligono p1=new Quadrado(); Quadrado q1=(Quadrado)p1; }

LES/PUC-Rio

Regras Gerais de Converso


Podemos sempre atribuir ancestral=descendente sem uma converso explcita, pois uma instncia de um descendente uma instncia de um ancestral; Podemos atribuir descendente=(descendente)ancestral. Neste caso, a compatibilidade ser verificada em tempo de execuo, e uma exceo poder ser levantada.

Poligono p1=new Quadrado(); Retangulo q1=(Quadrado)p1; //OK p1 um retngulo

Poligono p2=new Triangulo(); Quadrado q2=(Quadrado)p2; //erro de tempo de execuo //um tringulo no um quadrado

LES/PUC-Rio

Converso na Passagem de Parmetros


A converso de tipos tambm se aplica na passagem de parmetros. O exemplo a seguir ilustra esta situao:
public class UmaClasse { Object p; public UmaClasse(Object x) { p=x; } } public static void main(String[] args) { Quadrado p1=new Quadrado(); UmaClasse u=new UmaClasse(p1); //Object ancestral de todas //as classes }
LES/PUC-Rio 9

O Operador instanceof (1)


O trecho de cdigo abaixo ir gerar uma exceo quando for feita uma tentativa de converso do terceiro elemento do array (Triangulo) para o tipo Retangulo:
public class Main { public static void main(String[] args) { Poligono []lst=new Poligono[3]; Retangulo x; lst[0]=new Retangulo(); lst[1]=new Retangulo(); lst[2]=new Triangulo(); for(Poligono p:lst) x=(Retangulo)p; } }
Exception in thread "main" java.lang.ClassCastException: Triangulo cannot be cast to Retangulo at Main.main(Main.java:19)

LES/PUC-Rio

10

O Operador instanceof (2)


Para evitar a ocorrncia de tais excees, a linguagem Java fornece um operador que permite testar o tipo de um objeto em tempo de execuo; A sintaxe deste operador a seguinte:
<varObj> instanceof <tipoObj>

O operador retorna true se o objeto <varObj> for uma instncia de <tipoObj>, ou de uma descendente da mesma; Caso contrrio, o operador retorna false.
LES/PUC-Rio 11

Exemplo

public class Main { public static void main(String[] args) { Poligono []lst=new Poligono[3]; Retangulo x; lst[0]=new Retangulo(); lst[1]=new Retangulo(); lst[2]=new Triangulo(); for(Poligono p:lst) if(p instanceof Retangulo) x=(Retangulo)p; } }

LES/PUC-Rio

12

Programa Captulo 5
Converso de Tipos Polimorfismo O Modificador final O Modificador abstract Exerccios IR e Lista Encadeada

LES/PUC-Rio

13

Polimorfismo (1)
Polimorfismo (poli- + -morfismo) a capacidade de assumir vrias formas; Em termos prticos, podemos dizer que um meio de usar um mesmo nome para se referir a vrios mtodos distintos; Em Java existem dois tipos de polimorfismo:
O primeiro, j visto, chamado de overloading (sobrecarga). Ele se resume a uma classe possuir vrios mtodos com o mesmo nome, mas com assinaturas distintas;

LES/PUC-Rio

14

Polimorfismo (2)
(cont)
O segundo, chamado overriding (sobrescrita), ocorre quando uma classe possui um mtodo com a mesma assinatura (nome, tipo e ordem dos parmetros) que um mtodo da sua superclasse; Quando isso acontece, dizemos que o mtodo da classe derivada sobrescreve o mtodo da superclasse.

LES/PUC-Rio

15

Sobrescrita
Na sobrecarga, a amarrao entre a chamada do mtodo e o mtodo em si resolvida em tempo de compilao (early binding ou amarrao esttica); Na sobrescrita, a amarrao entre a chamada do mtodo e o mtodo em si resolvida em tempo de execuo (late binding ou amarrao dinmica); Isso ocorre porque, como vimos anteriormente, uma referncia para uma classe pode, em tempo de execuo, referenciar objetos da prpria classe e objetos das suas classes derivadas.

LES/PUC-Rio

16

Sobrescrita - Exemplo
Sejam as classes C1 e C2 abaixo:
public class C1 { public void m1() { System.out.println("PUC-Rio"); } }

public class C2 extends C1 { public void m1() { System.out.println("Departamento de Informtica"); } }

LES/PUC-Rio

17

Sobrescrita Exemplo (1)


No primeiro exemplo, a chamada p1.m1() ir executar o mtodo m1() definido na classe C1, pois p1 referencia um objeto de C1 em tempo de execuo; Neste exemplo, a mensagem PUC-Rio ser exibida na console.
public class Ex09 { public static void main(String[] args) { C1 p=new C1(); p.m1(); } }

LES/PUC-Rio

18

Sobrescrita Exemplo (2)


No segundo exemplo, a chamada p1.m1() ir executar o mtodo m1() definido na classe C2, pois p1 referencia um objeto de C2 em tempo de execuo; Neste exemplo, a mensagem Departamento Informtica ser exibida no console.
public class Ex09 { public static void main(String[] args) { C1 p=new C2(); p.m1(); } }

de

LES/PUC-Rio

19

Sobrescrita Visibilidade
Quando acrescentamos um mtodo m2() na classe C2, o comando a seguir ir causar um erro de compilao?

public class Ex09 { public static void main(String[] args) { C1 p=new C2(); p.m2(); } }

LES/PUC-Rio

20

Programa Captulo 5
Converso de Tipos Polimorfismo O Modificador final O Modificador abstract Exerccios IR e Lista Encadeada

LES/PUC-Rio

21

O Modificador final
O modificador final j foi visto anteriormente. Naquela ocasio ele foi usado para definir constantes:
private final int x=2; //define uma constante inteira //cujo valor 2

Quando o modificador final usado em uma classe ficamos impedidos de criar subclasses da mesma.
public final class C3 {}

public class C4 extends C3 {} //erro: a classe final C3 //no pode se estendida

LES/PUC-Rio

22

O Modificador final Uso em Mtodos


Quando o modificador final usado em um mtodo ficamos impedidos de sobrescrev-lo.
public class C3 { public final void m3() { } }

public class C4 extends C3 { public void m3() //erro: o mtodo final m3() //no pode se sobrescrito { } }

LES/PUC-Rio

23

Programa Captulo 5
Converso de Tipos Polimorfismo O Modificador final O Modificador abstract Exerccios IR e Lista Encadeada

LES/PUC-Rio

24

O Modificador abstract (1)


Quando o modificador abstract usado na declarao de uma classe ele define que esta classe abstrata; Uma classe abstrata normalmente possui um ou mais mtodos abstratos; Um mtodo abstrato no possui implementao, seu propsito obrigar as classes descendentes a fornecerem implementaes concretas das operaes; Rotular um mtodo com abstrato nos obriga a declarar a sua classe como abstrata.

LES/PUC-Rio

25

O Modificador abstract (2)


Devemos declarar uma classe como abstrata quando as trs condies a seguir forem verdadeiras:
Vrias subclasses de uma certa classe sero definidas; Todas as instncias das subclasses sero tratadas como instncias da superclasse abstrata; A superclasse, por si s, no deve ser instanciada, pois ela no contm todas as informaes necessrias para tal.

LES/PUC-Rio

26

O Modificador abstract Exemplo (1)


Tomemos a classe java.awt.Component exemplificarmos o conceito de classe abstrata; para

A classe Component a superclasse de muitas classes Java usadas para a construo de interfaces grficas com os usurios (botes, labels, menus, campos de texto e etc.); Dessa forma, a classe Component atende ao primeiro requisito apresentado anteriormente para se tornar uma classe abstrata: ela possui vrias subclasses.

LES/PUC-Rio

27

O Modificador abstract Exemplo (2)


Um container um componente GUI cujo propsito agrupar e exibir uma coleo de objetos grficos; Devido grande diversidade de componentes visuais, no seria muito prtico fornecer um mtodo diferente para registrar cada tipo componente junto ao container; Logo, gostaramos de poder escrever o seguinte trecho de cdigo Java: myContainer.add(Component c); Neste ponto passamos a atender ao segundo requisito: por convenincia, iremos tratar todos os componentes como instncias da superclasse Component.

LES/PUC-Rio

28

O Modificador abstract Exemplo (3)


Os componentes grficos so objetos concretos. Logo, ele devero ser renderizados na tela do usurio; Uma instncia de Component, entretanto, no contm as informaes sobre a forma e o comportamento dos componentes grficos de modo a poder exibi-los; Apenas as subclasses de Component podero fazer a renderizao dos componentes, sobrescrevendo, para tal, o mtodo abstrato que foi declarado na classe Component; Com isso atendemos o terceiro e ltimo requisito: a classe Component no deve ser instanciada, pois ela no contm todas as informaes necessrias para tal.
LES/PUC-Rio 29

O modificador abstract Exemplo (4)


Abaixo apresentada a forma geral da classe Component. Ela uma simplificao da verdadeira classe java.awt.Component; O mtodo draw() tambm no existe como tal. Ele foi usado no lugar do mtodo paintComponent() com objetivos didticos.

public abstract class Component { public void setBackground(java.awt.Color c) { /* cdigo */} public void setVisible(boolean r) { /* cdigo */} public void setLocation(int x,int y) { /* cdigo */} public abstract void draw(); }

LES/PUC-Rio

30

O Modificador abstract Exemplo (5)


Alguns mtodos, como setBackground() e setVisible(), so aplicveis a todos os componentes; logo, podem ser implementados na prpria classe Component; Outros, como o mtodo draw(), devem ser implementados pelas prprias subclasses, por isso devem se declarados abstratos e devem ser sobrescritos nas subclasses.
public class Button extends Component { public void draw() { /* cdigo */} } public class Scrollbar extends Component { public void draw() { /* cdigo */} }
LES/PUC-Rio 31

O Modificador abstract Exemplo (6)


O ltimo exemplo de cdigo se refere a uma classe que precise manipular componentes grficos; Ela ir tratar todos eles como instncias de Component; Quando houver necessidade de desenhar um componente qualquer ela enviar a mensagem draw() para o mesmo, que polimorficamente ir executar a implementao de draw() definida na classe do objeto referenciado em tempo de execuo.
public class Container { public void remove(Component comp) { /* cdigo */} public void add(Component comp) { comp.draw();} }
LES/PUC-Rio 32

INF1337 LINGUAGEM DE PROGRAMAO ORIENTADA A OBJETOS


Departamento de Informtica PUC-Rio Andrew Diniz da Cosa andrew@les.inf.puc-rio.br