genÉricos - dei.isep.ipp.ptnfreire/java - genéricos.pdf · herança em parâmetros de tipo...
Post on 14-Dec-2018
244 Views
Preview:
TRANSCRIPT
Nelson Freire (ISEP–DEI-PPROG 2014/15) 1/23
GENÉRICOS
(Livro Big Java, Late Objects – Capítulo 18)
Paradigmas da Programação PPROG
Nelson Freire (ISEP–DEI-PPROG 2014/15) 2/23
Noção de Genérico
Interesse dos Genéricos
Tipos Parametrizados
Implementação
Classe Genérica
Método Genérico
Genéricos e Herança
Tipos Wildcard
Type Erasure
Contexto Estático
Bibliografia
Sumário Genéricos
Nelson Freire (ISEP–DEI-PPROG 2014/15) 3/23
Genéricos
Genéricos
Facilidade do Java
Java 5 (2004)
Atual
Java 8 (2014)
Permite construção
Tipos
Classes
Interfaces
Métodos
Construções designadas
Genéricas
Exemplos
Tipos genéricos
Classes genéricas
Interfaces genéricas
Métodos genéricos
Para funcionarem com objetos de vários tipos.
Noção de Genérico 1/2
Nelson Freire (ISEP–DEI-PPROG 2014/15) 4/23
Genéricos
Tipos e Métodos Genéricos
Têm um/mais parâmetros de tipo genérico // genérico = não concreto ; Ex: tipo E
Funcionam como variáveis // análogo aos parâmetros de métodos
Passagem de tipos … concretos // Ex: tipo String
Exemplos
Exemplo Declaração ... com tipo(s) genérico(s) Uso ... com vários tipos referência concretos
(Instâncias de tipo genérico)
Classe Genérica
public class ArrayList<E> ...
// E: parâmetro de tipo genérico
// <...> parêntesis angulares
// Variável
ArrayList<Figura> f
ArrayList<Pessoa> p
Interface Genérica
public interface Map<K,V>
// K e V: parâmetros de tipo genérico
Map<Integer,String>
Map<Departamento,
List<Empregado> >
Método Genérico
public static void shuffle(List<?> list)
// Classe Collections
// ?: parâmetro de tipo genérico = qualquer tipo
Collections.shuffle(f)
Collections.shuffle(p)
Noção de Genérico 2/2
Nelson Freire (ISEP–DEI-PPROG 2014/15) 5/23
Genéricos Interesse dos Genéricos 1/2
Programação mais segura
Mais robusta
Reduzir possibilidade de erros de execução
Devido a excessivos downcastings
Problema
Exemplo
// Contentor que permite guardar objetos de qualquer tipo
List figuras = new ArrayList(); // Elementos tipo Object
// Preenchimento do contentor
figuras.add( new Circulo() );
figuras.add( new Rectangulo() );
figuras.add( new Pessoa() ); // Adicionado objeto não Figura // Compilador aceita qualquer objeto
// Varrimento do contentor para mostrar áreas
for( Object obj : figuras )
System.out.println(((Figura) obj).area() );
Retangulo
area()
Circulo
area()
Figura
area()
Downcasting do objeto Pessoa provoca erro de execução
programação insegura
Nelson Freire (ISEP–DEI-PPROG 2014/15) 6/23
Genéricos Interesse dos Genéricos 2/2
Programação mais segura
Solução
Exemplo
Usando tipo genérico ArrayList<E>
// Contentor para guardar apenas objetos tipo Figura
List<Figura> figuras = new ArrayList(); // Elementos tipo Figura
// Preenchimento do contentor
figuras.add( new Circulo() );
figuras.add( new Rectangulo() );
figuras.add( new Pessoa() ); // ERRO de COMPILAÇÃO // Compilador só aceita objetos Figura
// Varrimento do contentor para mostrar áreas
for( Figura figura : figuras )
System.out.println( figura.area() );
Retangulo
area()
Circulo
area()
Figura
area() Não há downcasting
programação segura
Nelson Freire (ISEP–DEI-PPROG 2014/15) 7/23
Definição
Tipo obtido por instanciação do tipo genérico, substituindo os parâmetros de tipo genérico (ex: E) por tipos referência concretos (ex: String)
Exemplo
Interface List genérica
Tipos Concretos
Só tipos referência // tipos primitivos são ilegais
Tipo Parametrizado 1/2 Genéricos
(Parâmetro Tipo Genérico) (Parâmetro Tipo Concreto)
public interface List<E> … {
…
boolean add(E e);
}
public interface List<String> … {
…
boolean add(String e)
}
Tipo Genérico ( Ex: List<E> )
Tipo Parametrizado ( Ex: List<String> )
instanciado
substituído
Instanciação de Tipo Genérico
Nelson Freire (ISEP–DEI-PPROG 2014/15) 8/23
Pode ser usado
Declarações
Variáveis … locais/atributos
Parâmetros … de métodos/construtores
Tipos de retorno … de métodos
Tipo Parametrizado 2/2 Genéricos
public class DemoUsoTipoParametrizado {
…
private List<String> variavel;
…
public DemoUsoTipoParametrizado(List<String> lista){ … }
…
public void metodo1(List<Pessoa> lista){ … }
…
public List<String> metodo2(){
…
List<String> lista = new ArrayList();
…
}
}
Uso de Tipo Parametrizado
Nelson Freire (ISEP–DEI-PPROG 2014/15) 9/23
Parâmetros de Tipo Genérico (1/2)
Declaração
A seguir ao nome da classe Entre parêntesis angulares // < ... >
Especifica variáveis ... de instância
Uma por parâmetro de tipo genérico
Separadas por vírgulas
Nome de variáveis Pode ser qualquer Por convenção
Letra maiúscula
public class ArrayList<E> … {
…
public boolean add(E e){…}
}
Declaração de ArrayList Genérico
Nome de Variável Tipo Genérico
Significado
E Tipo de elemento de uma coleção
K Tipo key num mapa
V Tipo value num mapa
T Tipo genérico
S, U Tipos genéricos adicionais
Convenção Java
Genéricos Implementação de Classe Genérica 1/2
public class HashMap<K,V> … {
…
public V put(K key, V value){…}
}
Declaração de HashMap Genérico
Nelson Freire (ISEP–DEI-PPROG 2014/15) 10/23
Parâmetros de Tipo Genérico (2/2)
Usados
Só contexto de instância
Atributos de instância
Construtores
Tipos de Parâmetros
Corpo
Métodos de instância
Tipo de Parâmetro
Tipo de Retorno
Corpo
Classes internas
Não-estáticas
public class DemoClasseGenerica<T> {
…
private T variavel;
…
public DemoClasseGenerica(T obj){…}
…
public void metodo1(T obj){…}
public T metodo2(){…}
public T metodo3(T obj) {…}
…
private class classeInterna<T> … {…}
}
Exemplos de Uso de Parâmetro de Tipo Genérico
Genéricos Implementação de Classe Genérica 2/2
Parâmetro de tipo genérico no cabeçalho da classe
Ilegal em contexto estático
Variáveis estáticas
Métodos estáticos
Classe internas estáticas
Nelson Freire (ISEP–DEI-PPROG 2014/15) 11/23
Método Genérico
Método com um/mais parâmetros de tipo genérico
Implementação de Método Genérico
Genéricos Implementação de Método Genérico 1/2
Tipo de Classe Tipo de Método Parâmetros de Tipo Utilizáveis
Classe Genérica
Instância
Próprios
Cabeçalho da classe
Classe (estático) Próprios
Classe Não-Genérica
(sem parâmetros de tipo genérico)
Instância Próprios
Classe (estático) Próprios
Nelson Freire (ISEP–DEI-PPROG 2014/15) 12/23
Método Genérico de Classe Não-Genérica
Especifica tipo genérico próprio
Declaração
Antes do tipo de retorno
Exemplo
Método de classe
Invocação
Chamada convencional
Exemplo
Servicos.imprimir( nomes ); // String[] nomes
Não é preciso … indicar o tipo concreto do parâmetro de tipo genérico
Compilador deduz o tipo referência concreto // tipos primitivos ilegais
public class Servicos {
…
public static <T> void imprimir( T[] vetor ) {
…
}
}
Método que imprime qualquer tipo de vetor
Genéricos Implementação de Método Genérico 2/2
Nelson Freire (ISEP–DEI-PPROG 2014/15) 13/23
Herança em Parâmetros de Tipo Concreto
Não implica herança de classes parametrizadas
Exemplo
ArrayList<Figura> e ArrayList<Retangulo>
Não existe relação de herança entre arraylists
Retangulo é subtipo de Figura
Parâmetros de tipo estão relacionados por herança
Não é possível:
ArrayList<Retangulo> listaRetangulos = new ArrayList();
ArrayList<Figuras> listaFiguras = listaRetangulos; // Ilegal
Justificação
Caso contrário
Possível adicionar objetos de tipos não relacionados por herança a contentor
Exemplo
ArrayList<Figura> figuras = new ArrayList<>();
ArrayList<Retangulo> retangulos = new ArrayList<>();
...
figuras = retangulos; // Se fosse legal ...
figuras.add( new Circulo() ); // ... era possível adicionar um circulo ... aos retangulos
Genéricos
Retangulo
area()
Circulo
area()
Figura
area()
Genéricos e Herança 1/2
Nelson Freire (ISEP–DEI-PPROG 2014/15) 14/23
Implicações da Limitação
Exemplo
Tipo Parametrizado
MinhaLista<Figura>
Parâmetro List<E>
Permite Passagem
Listas de tipo E
Exemplo
new MinhaLista( new ArrayList<Figura>() )
Não Permite Passagem
Listas de subtipos/supertipos de E
Exemplo
new MinhaLista( new ArrayList<Circulo>() )
Ultrapassar Limitação
Tipos Wildcard
Genéricos
Retangulo
area()
Circulo
area()
Figura
area()
Genéricos e Herança 2/2
public class MinhaLista<E> {
…
public MinhaLista(List<E> lista){…}
…
}
Nelson Freire (ISEP–DEI-PPROG 2014/15) 15/23
Interesse
Restringir os tipos concretos passados através de parâmetros genéricos
Tipos Wildcard
Tipo Wildcard
Tipo desconhecido // não é preciso conhecer tipo específico
Exemplo
Construtor
Cria arraylist com elementos de c
Não precisa de saber ... tipo específico dos elementos de c
Permite elementos de c do tipo/subtipo de E
Genéricos
Nome Sintaxe Significado Obs
Wildcard com restrição inferior ? extends B Qualquer tipo/subtipo de B (limitado ao tipo e subtipos de
B)
? = qualquer tipo extends = tipo/subtipo B = classe/interface
Wildcard com restrição superior ? super B Qualquer tipo/supertipo de B super = tipo/supertipo
Wildcard sem restrições ? Qualquer tipo
Tipos Wildcard 1/5
public class ArrayList<E> … {
…
public ArrayList(Collection<? extends E> c) { … }
}
Nelson Freire (ISEP–DEI-PPROG 2014/15) 16/23
Wildcard com Restrição Inferior
Restrição inferior do tipo limitado ao tipo e subtipos
Exemplo
Construtor
Não precisa de saber tipo específico de elementos de c
Permite elementos de c do tipo/subtipo de E
Exemplo - ArrayList<Figura>
List<Figura> listaFiguras = new ArrayList(listaCirculos);
List<Circulo> listaCirculos = new ArrayList();
...
List<Figura> listaFiguras = new ArrayList(listaRetangulos);
List<Retangulo> listaRetangulos = new ArrayList();
Genéricos Tipos Wildcard 2/5
Nome Sintaxe Significado Obs
Wildcard com restrição inferior ? extends B Qualquer tipo/subtipo de B ? = qualquer tipo extends = subtipo B = classe/interface
public class ArrayList<E> … {
…
public ArrayList(Collection<? extends E> c) { … }
}
Retangulo Circulo
Figura
Nelson Freire (ISEP–DEI-PPROG 2014/15) 17/23
Wildcard com Restrição Superior
Restrição superior do tipo limitado ao tipo e supertipos
Exemplo
Método sort
Não precisa de saber tipo específico de objetos comparáveis
Permite objeto Comparator de tipo/supertipo de E
Exemplo
ArrayList<Circulo>
Comparator<Circulo>
Comparator<Figura>
Figura = supertipo de Circulo
Compara objetos tipo Figura Compara objetos tipo Circulo
Genéricos Tipos Wildcard 3/5
Nome Sintaxe Significado Obs
Wildcard com restrição superior ? super B Qualquer tipo/supertipo de B ? = qualquer tipo super = supertipo B = classe/interface
public class ArrayList<E> … {
…
public void sort(Comparator<? super E> c){ … }
}
Retangulo Circulo
Figura
Nelson Freire (ISEP–DEI-PPROG 2014/15) 18/23
Wildcard sem Restrição
Exemplo
Método removeAll
Remove todos elementos armazenados em c
Não precisa de saber tipo específico dos elementos de c
Permite elementos de c de qualquer tipo
Nota
Collection<Object>
Não equivalente a Collection<?>
Só permite coleção com elementos tipo Object
Genéricos Tipos Wildcard 4/5
public class ArrayList<E> … {
…
public boolean removeAll(Collection<?> c)
}
Nome Sintaxe Significado
Wildcard sem restrições ? Qualquer tipo
Nelson Freire (ISEP–DEI-PPROG 2014/15) 19/23
Tipos de Declarações de Restrições:
Um Tipo
Múltiplos Tipos
Declarações de Um Tipo
Exemplos
<?>
<? extends E>
<? super T>
Declarações de Múltiplos Tipos
Tipos ligados
Carater &
Exemplo
<? extends Comparable<E> & Measurable> // tipos de interfaces
Genéricos Tipos Wildcard 5/5
Nelson Freire (ISEP–DEI-PPROG 2014/15) 20/23
Máquina Virtual do Java (JVM)
Não trabalha com
Tipos genéricos
Métodos genéricos
Razão
Genéricos mais recentes que a JVM
Substitui parâmetros de tipo
Por tipos não parametrizados
Pelo tipo
Object // se não houver restrições
Da restrição
Exemplos
ArrayList<E>
E substituído por Object
ArrayList ... com elementos de tipo Object // resulta numa classe normal
<E extends Measurable>
E substituído por Measurable
Problema
Introduz limitações nos genéricos
Genéricos JVM Substitui Parâmetros de Tipo (Type Erasure) 1/2
Nelson Freire (ISEP–DEI-PPROG 2014/15) 21/23
Limitações
Impossível construir objetos de tipo genérico
Exemplos
new E() // Se E substituído por Objet new Object() – nem sempre desejável // Alternativa: ArrayList<E>
new E[20] // Array de tipo genérico
Construção de array de tipo genérico
Limitação pode ser ultrapassada
Usando técnica Reflection
JVM
Guarda objeto Class
Por cada classe carregada
Objeto Class tem
Informação sobre uma classe
Métodos para construir novos objetos dessa classe
Dado um array a de tipo genérico
Class objCA = a.getClass(); // obter objeto Class do array
Class objCE = objCA.getComponentType(); // obter objeto Class elementos
Object[] novoArray = Array.newInstance(objCE, tamanho); // criar array
Genéricos JVM Substitui Parâmetros de Tipo (Type Erasure) 2/2
Nelson Freire (ISEP–DEI-PPROG 2014/15) 22/23
Parâmetros de Tipo Genérico de uma Classe
São variáveis de instância
Não podem ser usados em contexto estático
Variáveis estáticas
Métodos estáticos // alternativa: adicionar parâmetros de tipo genérico
Classes internas estáticas // alternativa: adicionar parâmetros de tipo genérico
Contexto Estático Genéricos
Nelson Freire (ISEP–DEI-PPROG 2014/15) 23/23
Livro
Big Java, Late Objects
Cay S. Horstmann
2013
John Wiley & Sons
Tutorial
http://docs.oracle.com/javase/tutorial/java/generics/
Bibliografia Genéricos
top related