Você está na página 1de 35

Programao

Orientada a Objetos
GCC110 Turmas 10A/22A
2016-2

Parte 17 Classes Genricas e Serializao

Jlio Csar Alves professores.dcc.ufla.br/~jcalves


Parte 17
Classes Genricas
Programao Genrica

Um conceito interessante que ainda no


conhecemos a programao genrica.

Ela chamada por alguns autores de tipos


parametrizados.
Programao Genrica

Suponha que no existissem as classes de lista na


API do Java e voc precisasse criar sua prpria Lista.

Voc usar sua lista no programa que est fazendo


para uma Locadora de Veculos, pois precisar de
uma lista de carros.
Criando uma lista de Carros
Provavelmente voc pensaria em fazer algo como:

public class ElementoLista {


Carro carro;
ElementoLista proximo;
public ElementoLista(Carro carro, ElementoLista proximo) // ...
public Carro getCarro() // ...
public ElementoLista getProximo() // ...
public void setProximo(ElementoLista proximo) // ...
}

public class Lista {


ElementoLista primeiroElemento;
int tamanho;
public Lista() {}
public void adicionar(Carro carro) // ...
public void remover(Carro carro) // ...
public Carro getCarro(int pos) // ...
public int getTamanho() // ...
}
E a lista de vendedores?

Mas ao desenvolver o sistema voc percebeu que


precisar tambm de uma lista de vendedores.

E agora como proceder, sem deixar de seguir os princpios


relacionados ao bom projeto de classes?

Se ns criarmos duas novas classes similares a Elemento e Lista, mas dessa vez para vendedores
estaremos criando novas classes muito parecidas com as anteriores (replicao de cdigo).

No temos como herdar da lista que criamos porque ela tem atributo do tipo carro que no tem
nada a ver com vendedores.

Como isso poderia ser resolvido?


public class ElementoLista {
J sei! s Object elemento;
criarmos uma ElementoLista proximo;
lista de
public ElementoLista(Object elemento, ElementoLista proximo) // ...
Objects!!!
public Object elemento() // ...
public ElementoLista getProximo() // ...
public void setProximo(ElementoLista proximo) // ...
}
public class Lista {
ElementoLista primeiroElemento;
int tamanho;
public Lista() {}
public void adicionar(Object elemento) // ...
public void remover(Object elemento) // ...
public Object getObject(int pos) // ...
public int getTamanho() // ....
}

Quais so os problemas dessa abordagem?


Lista de Objects inseguro

Esse cdigo perigoso!


Ele depende de converso de tipos (cast) ao buscar um
elemento e que podem ser feitos de forma equivocada.

Alm disso, dado o cdigo abaixo:


Carro carro1 = new Carro();
Vendedor vendedor1 = new Vendedor();

Lista listaCarros = new Lista();


listaCarros.adicionar(carro1);

Lista listaVendedores = new Lista();


listaVendedores.adicionar(vendedor1);
O que nos impede de cometer os erros abaixo?
listaCarros.adicionar(vendedor1);
Carro carro = (Carro)listaVendedores.getObject(0);
J sei, vamos usar herana! s
definirmos uma interface Elemento!

Faramos a lista de elementos do tipo


dessa Interface e tanto Carro quanto
Vendedor implementariam essa
interface.

Isso resolve o problema de precisarmos fazer o cast e de


colocarmos carros na lista de vendedores?
Programao Genrica

a que entra a Programao Genrica!

Ela nos permite criar uma classe que dependa de outra


(parmetro) sem especificar qual essa outra classe.

Somente quando usarmos a classe que indicamos no


cdigo a outra classe que estamos usando como
parmetro.
Programao Genrica

Antes de fazermos nossa Classe Genrica de Lista, vamos ver


um exemplo de classe Genrica que j utilizamos.

ArrayList<Animal> animais = new ArrayList<>();

ArrayList uma classe Nesse exemplo estamos


genrica (depende de outro fazendo um ArrayList de
tipo, parmetro, na hora que animais, ou seja, a classe
utilizada). ArrayList depende do tipo
Animal.

Vamos agora ento criar a nossa prpria classe genrica!


Classe Genrica

public class ElementoLista<T> { Nossa classe ElementoLista agora


depende de um tipo parametrizado T
Nossa lista agora T elemento;
guarda valores ElementoLista proximo;
do tipo T.
public ElementoLista(T elemento, ElementoLista proximo) // ...

public T elemento() // ...


public ElementoLista getProximo() // ...
public void setProximo(ElementoLista proximo) // ...
}
Assim como nossa classe Lista.

public class Lista<T> {


ElementoLista<T> primeiroElemento; Ao declarar uma lista agora, usamos:
int tamanho; Lista<Carro> listaCarros;
listaCarros = new Lista<>();
public Lista() {}
public void adicionar(T elemento) // ... Qual a vantagem dessa abordagem?
public void remover(T elemento) // ...
public T getValor(int pos) // ...
public int getTamanho() // ...
Classe Genrica

O compilador vai verificar o tipo dos elementos durante a


compilao. O que evitar erros de programao.

Carro carro1 = new Carro();


Vendedor vendedor1 = new Vendedor();

Lista<Carro> listaCarros = new Lista<Carro>();


listaCarros.adicionar(carro1);
Essa linha daria erro de
compilao porque o tipo
Lista<Vendedor> listaVendedores = new Lista<Vendedor>();
T da listaCarros Carro. listaVendedores.adicionar(vendedor1);

listaCarros.adicionar(vendedor1);
Carro carro = listaVendedores.getValor(0);

Essa linha daria erro porque o tipo


T da listaVendores Vendedor.
Programao Genrica

Programao genrica uma outra forma de alcanar a reutilizao


de software!
Conseguimos aproveitar o mesmo cdigo para classes diferentes.

Outras linguagens de programao tambm suportam Programao


Genrica. Em C++, por exemplo, usa-se templates (ou gabaritos).

Existem Padres de Projeto que podem ser implementados


usando Programao Genrica ao invs de herana.
Mtodos Genricos

Voc pode criar tambm mtodos genricos, ou seja, apenas o mtodo em si


depende de um tipo parametrizado.

Suponha, por exemplo, que voc queira criar um mtodo que pega os
elementos de um vetor (simples) e coloca em uma coleo.
Mas voc quer usar esse mtodo para vetores e colees de quaisquer tipos.

O mtodo agora depende de


um tipo parametrizado T.
public static <T> void vetorParaColecao(T[] vetor, Collection<T> colecao) {
for (T elemento : vetor) {
colecao.add(elemento);
}
Mtodos Genricos

Ao utilizar o mtodo, o compilador infere o tipo a ser tratado.

public static <T> void vetorParaColecao(T[] vetor, Collection<T> colecao) {


for (T elemento : vetor) {
colecao.add(elemento);
}

Como o mtodo genrico, podemos utiliz-lo para diversos tipos diferentes:

String[] v = new String[100];


Collection<String> c = new Collection<>();

vetorParaColecao(v, c);

Carro[] v = new Carro[100];


Collection<Carro> c = new Collection<>();

vetorParaColecao(v, c);
Programao Genrica e a API Java

Java utiliza muito o conceito de Programao Genrica em


suas implementaes de Colees.

Fonte: https://docs.oracle.com/javase/tutorial/collections

Interface Collection<E> Interface Queue<E>

Interface List<E> Interface Map<K,V>


Repare que uma classe
pode ter mais de um tipo
parametrizado.
Programao Genrica e a API Java

Vamos aproveitar para conhecer para que serve cada uma dessas interfaces.

Interface raiz da hierarquia, representa uma coleo de objetos


Interface Collection<E> (elementos).

Interface Set<E> Uma coleo que no contm elementos duplicados.

Interface List<E> Uma coleo que pode ter elementos duplicados e esses elementos esto
em determinada ordem.

Interface Queue<E> Representa uma fila*.

Pode ser usado como pilha e/ou filha. Insere/remove elementos do incio
Interface Deque<E>
ou do fim.

Interface Map<K,V> Mapeia chaves a valores. No pode ter chaves duplicadas.

Lembre-se que essas so as interfaces. Usamos os objetos das classes que as implementam!
A classe Collections do Java

A classe Collections possui mtodos teis interessantes (como


a ordenao por exemplo).

Podemos fazer:
Collections.sort(minhaColeo).

List<Carro> carros = new ArrayList<Carro>();


carros.add( new Carro( "Gol", 34000 ) );
carros.add( new Carro( "Ferrari", 600000 ) );
carros.add( new Carro( "Fusca", 8000 ) );

Collections.sort(carros); O mtodo sort ordena a coleo


passada por parmetro.
for ( Carro c : carros ) {
System.out.println( c );
}
Mas como a ordenao sabe qual carro menor
que o outro, ou seja, qual deve ser a ordem?
A classe Collections do Java

Para a ordenao, a classe dos objetos que esto na lista precisa


implementar a interface Comparable.

public class Carro implements Comparable<Carro> {


Devemos implementar a interface
private final String nome; Comparable (ela usa tipo parametrizado).
private float preco;

// .. outros atributos e mtodos Precisamos implementar o mtodo compareTo


da interface Comparable.
@Override O mtodo compareTo deve comparar dois
public int compareTo(Carro c) { objetos do tipo parametrizado e retornar:
return this.preco - c.preco; Um valor positivo caso o objeto para o qual o
} mtodo foi chamado for maior que o
} passado por parmetro.
Supondo ento que queremos ordenar os Um valor negativo em caso contrrio.
carros por preo, a subtrao acima retorna
os valores conforme esperado. E zero caso os objetos sejam iguais.
Ns geralmente no usamos o compareTo
diretamente. Mas o mtodo de ordenao,
por exemplo, usa.
A classe Collections do Java

A classe Collections possui ainda muitos outros mtodos


teis. Vale a pena conferir a documentao.

Exemplos:
Busca Binria.
Adicionar elementos de uma lista em outra.
Dizer se duas listas no tem elementos em comum.
Contar quantidade de vezes que um objeto aparece.
Maior elemento.
Menor elemento.
Substituir ocorrncias de um elemento por outro.
Inverter.
Embaralhar.
Parte 17
Serializao
Arquivos Binrios: Escrita

E aquele
Java nos permite salvar objetos inteiros (com todos os negcio de
seus atributos tambm) utilizando um nico comando. arquivo
binrio?
Para isso, precisamos primeiro que cada classe que ter
objetos salvos implemente a interface Serializable.

A interface Serializable no possui nenhum mtodo, ela serve apenas para indicar ao Java em
tempo de execuo que os objetos daquela classe podero ser salvos em formato binrio.
Arquivos Binrios: Escrita

Para salvar um arquivo binrio podemos usar as classes FileOutputStream e


ObjectOutputStream e os mtodos writeObject e close da ltima.
Arquivos Binrios: Leitura

Para recuperar um arquivo binrio podemos usar as classes FileInputStream e


ObjectInputStream e os mtodos readObject e close da ltima.
Arquivos Binrios

Salvar objetos em formato binrio como mostrado til.


Mas devemos nos lembrar que possui uma limitao importante:
Imagine que a aplicao j est em uso e temos vrias informaes salvas.
Se agora precisarmos alterar nosso objeto (adicionar/remover campos, ou alterar
um campo), ns no conseguiremos mais recuperar os dados salvos.

A necessidade de alterar classes depois de prontas muito comum em aplicaes


reais.
Portanto, arquivos texto tm uma vantagem nesse aspecto.

Na prtica grandes sistemas guardam seus dados em bancos de dados


e so utilizadas ferramentas de ORM (Object-Relational Mapping) para
guardar os objetos nesses bancos.
Parte 17
Exerccios

27
Indique se as afirmativas so verdadeiras ou falsas e justifique sua resposta:

a) Todos os mtodos de uma classe abstrata devem ser declarados como abstratos.

b) Suponha que uma subclasse possua um mtodo pblico que no existe na


superclasse. No possvel chamar esse mtodo utilizando uma varivel do tipo
dessa subclasse.

c) Se uma superclasse declara um mtodo abstrato, a subclasse deve implementar


esse mtodo.

d) Um objeto de uma classe que implementa uma interface pode ser visto como um
objeto do tipo daquela interface.

Fonte: http://web.cerritos.edu/
Como o polimorfismo
promove a extensibilidade?

Fonte: http://web.cerritos.edu/
O termo interface utilizado em, pelo menos, trs diferentes
contextos em programao a objetos. Explique cada um dos conceitos
explicitando a diferena entre eles:

a) Interface de uma classe.

b) Interface como tipo de dado.

c) Interface Grfica de usurio.

Fonte: Lista de Exerccios 3


Escreva algumas linhas de cdigo em Java que
resultem em uma situao na qual uma varivel x
tenha o tipo esttico T e o tipo dinmico D.

Fonte: Barnes e Kolling 4 Ed.


Suponha que voc est trabalhando em um jogo de guerra. Imagine e descrevas duas
situaes nas quais ocorram cada um dos relacionamentos abaixo:

1. Associao

2. Herana

3. Agregao

4. Composio
Faa um diagrama de classes UML para a seguinte situao:
Queremos modelar um sistema de gesto de voos e pilotos.
Uma companhia area opera voos. Cada companhia area tem um ID.
Cada voo tem uma identificao de um aeroporto de partida e um aeroporto de chegada.
Cada voo tem um piloto e um co-piloto, e eles usam aeronaves de um determinado tipo; um voo
tem tambm uma hora de partida e uma hora de chegada.
Uma companhia area possui um conjunto de aeronaves de diferentes tipos.
Uma aeronave pode estar em operao ou em manuteno.
Em um dado momento, uma aeronave pode estar voando ou em solo.
A empresa tem um conjunto de pilotos: cada piloto tem um nvel de experincia: no mnimo 1 e no
mximo 3.
Um tipo de avio pode precisar de um determinado nmero de pilotos, cada um com um papel
diferente (ex: capito, co-piloto, navegador).
Deve haver, pelo menos, um capito e um co-piloto, e o capito deve ser um pilito de nvel 3.

Fonte: http://softeng.polito.it/