Baixe o app para aproveitar ainda mais
Prévia do material em texto
25/11/13 Genéricos em Java www.inf.pucrs.br/flash/alpro2/present/U03_projeto/01b-genericos/handout.html 1/6 Genéricos em Java Prof. Marcelo Cohen 08/2013 Genéricos em Java Genéricos A classe ArrayList Genéricos Como? Convenção Convenção Instanciação Exemplos de aplicação Classe que armazena uma String Classe genérica, que armazena qualquer tipo Considerações sobre genéricos Outro exemplo: classe Produto Classe Produto genérico Exemplos de instanciação Classe com mais de um parâmetro de tipo Exemplos de instanciação Curiosidades sobre genéricos Restrições Restrições (2) Exercícios Exercícios Exercícios (2) Exercicios (3) Exercicios (4) Bibliografia recomendada Genéricos em Java Versão para impressão Genéricos Programação genérica consiste na criação de estruturas de programação que podem ser usadas com tipos de dados diferentes Exemplo: a classe ArrayList<???> é genérica Estrutura de dados que pode ser instanciada para coleções de diferentes tipos de dados O tipo é verificado durante a compilação do programa A classe ArrayList 25/11/13 Genéricos em Java www.inf.pucrs.br/flash/alpro2/present/U03_projeto/01b-genericos/handout.html 2/6 Overview Package Class Use Tree Deprecated Index Help Java™ Platform Standard Ed. 7 Prev Class Next Class Frames No Frames Summary: Nested | Field | Constr | Method Detail: Field | Constr | Method java.util Class ArrayList<E> java.lang.Object java.util.AbstractCollection<E> java.util.AbstractList<E> java.util.ArrayList<E> All Implemented Interfaces: Serializable, Cloneable, Iterable<E>, Collection<E>, List<E>, RandomAccess Direct Known Subclasses: AttributeList, RoleList, RoleUnresolvedList public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable Genéricos Uma das principais modificações do Java 1.5 Permitem criar elementos com tipos parametrizáveis Fornecem uma maneira de comunicar o tipo de uma coleção ou atributo ao compilador Verificação em tempo de compilação Quando o compilador conhece o tipo do elemento, ele pode verificar se o mesmo está sendo usado corretamente e pode inserir casts corretamente Evitam a escrita de código repetitivo e sujeito a erros de execução resultante do uso excessivo de conversores de tipo (casts) Como? Em Java pode-se fazer programação genérica usando-se herança (será visto mais adiante) ou variáveis de tipo Uma classe genérica terá uma ou mais variáveis de tipo O uso de variáveis de tipo torna o código mais seguro e simples de ler Convenção Usam-se letras maiúsculas individuais para especificar parâmetros de tipo Nome da variável de tipo Significado E Elemento de uma coleção. K Chave de um mapa V Valor em um mapa T Tipo genérico S, U Tipos adicionais Convenção Parâmetros de tipo são declarados entre < e > ao lado do nome da classe Uma vez declarado, um parâmetro de tipo pode ser usado no lugar de qualquer tipo de dado (declaração de variáveis e atributos, parâmetros e valores de retorno) 25/11/13 Genéricos em Java www.inf.pucrs.br/flash/alpro2/present/U03_projeto/01b-genericos/handout.html 3/6 Instanciação Como instanciar? NomeClasseGenerica<Tipo1, Tipo2, ... > n = new NomeClasseGenerica<>(); Java 7: não é necessário repetir os parâmetros de tipo do lado direito da atribuição Usa-se “<>” (válido para quaisquer quantidade de parâmetros de tipo) Observação: a ausência do parâmetro de tipo em uma classe genérica implica na utilização do tipo Object como default (será discutido mais adiante) Exemplos de aplicação Classe que armazena uma String public class Dado { private String dado; public Dado(String d) { dado = d; } public String getDado() { return dado; } } ... // Uso correto Dado d = new Dado(“Oi”); String x = d.getDado(); ... // Uso incorreto: tipo deve ser String Dado d = new Dado(new Pessoa(“Ze”,20)); Pessoa x = (Pessoa)d.getDado(); E se quiséssemos uma classe capaz de armazenar qualquer tipo? Classe genérica, que armazena qualquer tipo public class Dado<E> { private E dado; public Dado(E d) { dado = d; } public E getDado() { return dado; } } ... Dado<String> d = new Dado<>(“Ola”); String x = d.getDado(); ... Dado<Pessoa> d = new Dado<>(new Pessoa(“Ze”,20)); Pessoa x = d.getDado(); ... Neste caso, E é a especificação do parâmetro de tipo (qualquer um) Considerações sobre genéricos Java não cria um tipo específico para cada instância de uma estrutura genérica Durante a compilação as anotações entre "<" e ">" são apagadas, e ocorre uma tradução para código Java tradicional com os tipos e casts adequados Outro exemplo: classe Produto 25/11/13 Genéricos em Java www.inf.pucrs.br/flash/alpro2/present/U03_projeto/01b-genericos/handout.html 4/6 Analise a classe ao lado: <li>Imagine como poderíamos reutilizar esta classe se, dependendo da empresa onde o sistema for implantado, o código do produto pode ser: um inteiro? uma String? ou, eventualmente, um objeto da classe Codigo? <li>Solução: usar parâmetros de tipo!</li> public class Produto { private int codigo; private String descricao; private double preco; public Produto(int cod, String descr,double pr) { codigo = cod; descricao = descr; preco = pr; } public int getCodigo() { return codigo; } public String getDescricao() { return descricao; } public double getPreco() { return preco; } @Override public String toString() { return "Produto{" + "codigo=" + codigo + ", descricao=" + descricao + ", preco=" + preco + '}'; } } Classe Produto genérico public class Produto<T> { private T codigo; private String descricao; private double preco; public Produto(T cod,String descr, double pr) { codigo = cod; descricao = descr; preco = pr; } public T getCodigo() { return codigo; } public String getDescricao() { return descricao; } public double getPreco() { return preco; } @Override public String toString() { return "ProdutoG{" + "codigo=" + codigo + ", descricao=" + descricao + ", preco=" + preco + "}"; } } Exemplos de instanciação ProdutoG<String> p1 = new ProdutoG<String>("AA112","Radio",438); ProdutoG<Integer> p2 = new ProdutoG<Integer>(112,"Radio",438); ProdutoG<Double> p3 = new ProdutoG<Double>(112.3,"Radio",438); Classe com mais de um parâmetro de tipo public class ProdutoG2<T,U> { private T codigo; private String descricao; private U preco; public ProdutoG2(T cod, String descr, U pr) { 25/11/13 Genéricos em Java www.inf.pucrs.br/flash/alpro2/present/U03_projeto/01b-genericos/handout.html 5/6 codigo = cod; descricao = descr; preco = pr; } public T getCodigo() { return codigo; } public String getDescricao() { return descricao; } public U getPreco() { return preco; } @Override public String toString() { return "ProdutoG2 {" + "codigo=" + codigo + ", descricao=" + descricao + ", preco=" + preco + "}"; } } Exemplos de instanciação ProdutoG2P<Integer,Float> p4 = new ProdutoG2P<>(112,"TV",1276F); ProdutoG2P<String,Integer> p5 = new ProdutoG2P<>(“AB”,"TV",1276); Curiosidades sobre genéricos Restrições É possível criar genéricos limitados a uma certa "família" de classes Exemplo: public class MinhaLista<E extends Produto> { ... } O exemplo define uma classe MinhaLista que pode conter quaisquer elementos cujo tipo seja subclasse ou implementação de Produto Este tipo de restriçãoé chamado de "limite superior" (upper bounds) Não importando se Produto é uma classe ou interface usa-se a palavra reservada extends Futuramente serão vistas aplicações Restrições (2) É possível criar também restrições de limite inferior (lower bounds) que são de utilização mais rara Exemplo: public class MinhaLista<E> { ... public void metodo(List<? super Enlatado> li) { ... } } O exemplo apresenta uma lista cujos elementos devem ser Enlatado ou superclasses de Enlatado Por exemplo, se Enlatado é derivado de Produto, então Produto é um tipo de elemento aceito na coleção Exercícios Exercícios 1. Implemente uma classe Par que possa armazenar dois objetos declarados como tipos genéricos Demonstrar o uso da classe Par em uma classe App que possua o método main e permita criar e imprimir objetos par que contém cinco tipos diferentes de pares, como, por exemplo: <String, Double> (nome e nota de um aluno) <Integer,String> (código e nome de um funcionário) 25/11/13 Genéricos em Java www.inf.pucrs.br/flash/alpro2/present/U03_projeto/01b-genericos/handout.html 6/6 <Float,Float> (coordenadas x e y) Exercícios (2) 2. Imagine que uma empresa codifica seus produtos em 2 partes: as letras indicam o setor onde o produto é fabricado e os números são um código sequencial dentro do setor Ex: “IMP34”, “SEC1413”, ... Crie uma classe chamada Codigo para representar esses códigos e instancie a classe ProdutoG vista anteriormente usando a classe Codigo como tipo do código do produto 3. Imagine que os tipos dos componentes da classe Codigo podem variar: altere a classe Codigo para que use 2 parâmetros de tipo (para a primeira e a segunda partes do código) e use esta nova classe para instanciar a classe ProdutoG Exercicios (3) 4. Crie uma classe ValorM que representa um valor monetário, e use esta e a classe Codigo do exercício 2 para instanciar a classe ProdutoG2 vista anteriormente Exercicios (4) 5. Um dicionário é uma estrutura onde os elementos são armazenados sob uma chave. Por exemplo, podemos armazenar os dados sobre um automóvel usando como chave a placa. Para recuperar os dados do automóvel basta informar a placa (ao invés, por exemplo, da posição onde os dados foram armazenados) Usando dois arrays, crie uma classe Dicionario onde tanto a chave como o valor tem seu tipo definido por parâmetros de tipo Imagine que as seguintes operações devem estar disponíveis: add(K chave, V valor) - adiciona à chave K o valor V V get(K chave) - retorna o valor associado à chave K (se não encontrar, retorna null) Obs: para criar um array de genéricos, use: E[] vet = (E[]) new Object[TAMANHO]; Bibliografia recomendada Horstmann, capítulo 17 (Genéricos) Goodrich, seção 2.5.2 (Genéricos) Java Tutorial: Generics Java Generics FAQ (Avançado)
Compartilhar