Genéricos. Profa. Thienne Johnson EACH/USP

Documentos relacionados
Genéricos by Pearson Education do Brasil

Métodos Genéricos. Prof.: Michele Nasu Tomiyama Bucci

Profa. Thienne Johnson EACH/USP

Programação Orientada a Objetos

GENÉRICOS EM JAVA. Java Generics

Introdução a classes e objetos. Prof. Marcelo Roberto Zorzan

Introdução a classes e objetos. Prof. Marcelo Roberto Zorzan Prof a. Rachel Reis

Generics - Java. Fernando Santos. Programação Orientada a Objetos

AULA 6 - ARRAYS. Array de 10 elementos

Tipos, Literais, Operadores

Tipos, Literais, Operadores

Templates. BCC Programação Orientada a Objectos(POO) Departamento de Computação - UFOP

Programação Orientada a Objectos - P. Prata, P. Fazendeiro

5 Arrays. 5.1 Criando um array. 5.2 Inicializando arrays. c:\>java Array Janeiro tem 31 dias.

CONCEITOS BÁSICOS DE ORIENTAÇÃO A OBJETOS PROF. ME. HÉLIO ESPERIDIÃO

Linguagem Java. Introdução. Rosemary Silveira Filgueiras Melo

Análise de Programação

Array em Java. Figura 1 - Exemplo de um array de inteiros

UNIP - Ciência da Computação e Sistemas de Informação. Estrutura de Dados. AULA 5 Pilhas

Lição 4 Fundamentos da programação

Classes o Objetos. Classes, objetos, métodos e variáveis de instância

Tratamento de Exceções. Profa. Thienne Johnson EACH/USP

INF1337 LINGUAGEM DE PROGRAMAÇÃO ORIENTADA A OBJETOS

Classes, instâncias e métodos de acesso. prática

INF1636 PROGRAMAÇÃO ORIENTADA A OBJETOS

Algoritmos II prof. Daniel Oliveira

Programação Orientada a Objetos

Programação Orientada a Objetos

Linguagens de Programação

Recapitulando. Construtores: (Overload assinatura) public Circle() {...} public Circle(double x, double y, double r) {... }

Orientação a Objetos e Java

Paradigmas de Programação. Java First-Tier: Aplicações. Orientação a Objetos em Java (I) Nomenclatura. Paradigma OO. Nomenclatura

Vetores Unimensionais

Programação Orientada a Objectos - P. Prata, P. Fazendeiro

Ambientação com a Sintaxe de Java: parte 1

Linguagem de programação Java

Esta categoria mais geral, à qual cada objeto pertence, denominamos de classe; IFSC/POO + JAVA - prof. Herval Daminelli

9 Classes Abstractas e Interfaces

PROGRAMAÇÃO ORIENTADA A OBJETOS: OCULTAR INFORMAÇÕES E ENCAPSULAMENTO

Programação Orientada a Objetos para Redes de Computadores

Aula 03 Introdução à Java. Disciplina: Fundamentos de Lógica e Algoritmos Prof. Bruno Gomes

Lição 7 Array em Java

Programação Orientada a Objectos - P. Prata, P. Fazendeiro

Java e sua Sintaxe. Estrutura mínima de um programa em Java: public class Exemplo { }

Orientação a Objetos AULA 09

Programação Orientada a Objetos. Aula 1.9 this e static. Prof. Bruno Moreno

POO Programação Orientada a Objetos. Classes e Objetos 2

Programação Orientada a Objetos OUTROS MECANISMOS

Tratamento de Exceções cont. Profa. Thienne Johnson EACH/USP

Palavras Reservadas da Linguagem Java

Módulo Lógica Programação com aplicações em Java. Projeto khouse Profissionalizante Profª Larissa Brandão

Revisão. Classe e objeto Construtores Polimorfismo Sobrecarga Pacote padrão

Aula 3. Objetivos Sequências de escapes ; Um aplicativo que adiciona inteiro; Aritmética.

ALGORITMOS. Professor: Diego Oliveira. Aula 06 - Tipos Primitivos de Dados

Programação por Objectos. Java

Estruturas da linguagem C. 1. Identificadores, tipos primitivos, variáveis e constantes, operadores e expressões.

Apêndice A. Alguns construtores e métodos importantes e úteis da classe Vector são:

Algoritmos e Programação

A R R A Y S E E X C E P T I O N S P R O F. M E. H É L I O E S P E R I D I Ã O

PROGRAMAÇÃO JAVA. Parte 2

Revisões de PG. Programação Orientada por Objetos (POO) Centro de Cálculo Instituto Superior de Engenharia de Lisboa

Slide 1 Deitel/Deitel, 8e. Java Como programar Copyright 2010 Pearson Education

Métodos Computacionais

Introdução a classes e objetos by Pearson Education do Brasil

LÓGICA DE PROGRAMAÇÃO (JAVA) VARIÁVEIS. Professor Carlos Muniz

Universidade de Mogi das Cruzes Implementação Orientada a Objetos - Profª. Danielle Martin. Guia da Sintaxe do Java

Aula 3 POO 1 Classe e Objeto. Profa. Elaine Faria UFU

Especificam quem tem acesso a cada entidade, isto é, quem tem acesso a. cada classe e cada membro da classe (dados e métodos)

AULA TEÓRICA 7 Tema 7. Colecções (cont.) Vector Ø Criação Ø Manipulação

Linguagem de Programação II Implementação

Fundamentos Básicos da linguagem Java (Programação Orientada a Objetos) Prof. Responsáveis Wagner Santos C. de Jesus

Introdução. Universidade Federal de Uberlândia. Programação Orientada a Objetos. Prof. Fabiano Dorça

Iteradores. Iteradores. Isabel Harb Manssour. Roteiro. Coleções

3. Linguagem de Programação C

Orientação a objetos. Programação. Orientada a Objetos. Orientação a objetos. Orientação a objetos. Abstração e encapsulamento

Programação Orientada a Objetos para Redes de Computadores. Arrays. Arrays

Linguagem C: Introdução

Programação Orientada a Objectos - P. Prata, P. Fazendeiro. Hierarquia de classes e mecanismo de ligação

Programação Orientada a Objetos

Laboratório de programação II

Programação Orientada a Objetos. Métodos e Atributos. Métodos. Métodos. Alexandre César Muniz de Oliveira. Parte III

Interfaces. Universidade Católica de Pernambuco Ciência da Computação. Prof. Márcio Bueno.

Sintaxe da linguagem Java

Introdução à Linguagem de Programação Java 1 INTRODUÇÃO À LINGUAGEM DE PROGRAMAÇÃO JAVA

Java Variáveis e Controle Fluxo

Instituto Superior de Engenharia de Lisboa

JAVA COLLECTIONS API: LISTAS

DCC / ICEx / UFMG. Membros de Classes. Eduardo Figueiredo.

AULA 02 DADOS PRIMITIVOS E EXERCÍCIOS

Variáveis primitivas e Controle de fluxo

Aula 2 POO 1 Prática. Profa. Elaine Faria UFU

Programação Java. - Herança e Polimorfismo - Marco Fagundes Marco Fagundes -

Classes e Objetos INTRODUÇÃO À ORIENTAÇÃO A OBJETOS COM JAVA - MÓDULO II. Classes. Objetos. Um modelo para a criação de objetos

Arrays em Java. Alberto Costa Neto DComp - UFS

4. Estruturas Fundamentais de Programação em C

Coleções. Prof. Marcelo Roberto Zorzan

Transcrição:

Genéricos Profa. Thienne Johnson EACH/USP

Java, como programar, 6ª edição Deitel & Deitel Capítulo 18 Material complementar http://wps.prenhall.com/br_deitel_comoprogra_6/

Todas as classes em Java herdam, direta ou indiretamente, da classe Object (pacote java.lang) Classes que implementam estruturas de dados desenvolvidas em Java manipulam e compartilham objetos da classe Object Essas classes não podem manipular variáveis de tipos primitivos, mas podem manipular objetos de classes empacotadoras de tipos

Todo tipo primitivo tem uma classe empacotadora de tipo correspondente (no pacote java.lang) Boolean Byte Character Double Float Integer Long Short

Toda classe empacotadora de tipo permite manipular valores de tipo primitivo como objetos Obs: classes empacotadoras de tipo são final, então não é possível estendê-las

Métodos relacionados a um tipo primitivo encontram-se na classe empacotadora de tipo correspondente Ex: O método parseint, que converte uma String em um valor int, encontra-se na classe Integer

Uma conversão boxing converte um valor de um tipo primitivo em um objeto da classe empacotadora de tipo correspondente Uma conversão unboxing converte um objeto de uma classe empacotadora de tipo em um valor do tipo primitivo correspondente J2SE 5.0 permite que essas conversões sejam feitas automaticamente (chamadas de autoboxing e autounboxing)

//cria integerarray Integer[] integerarray = new Integer[5]; //autoboxing integerarray[0] = 10; // atribui Integer 10 a integerarray[0] //auto-unboxing int value = integerarray[0]; // obtem valor int de Integer

Questão 1: O que fazer para escrever um único método de ordenação ordena para elementos em um array de Integer, em um array de String ou em um array de qualquer tipo que suporte ordenação?

Questão 2: O que fazer para escrever uma única classe Stack que seria utilizada como uma pilha de inteiros, uma pilha de números de ponto flutuante, uma pilha de String ou uma pilha de qualquer outro tipo?

Questão 3: O que fazer para detectar nãocorrespondências de tipos em tempo de compilação (segurança de tipos em tempo de compilação)? Ex: se uma pilha armazenasse somente inteiros, tentar inserir uma String nessa pilha.

Genéricos: recurso que fornece um meio de criar os objetos gerais citados nas Questões 1, 2 e 3 Classes genéricas: permite que o programador defina, com uma única declaração de classe, um conjunto de tipos relacionados

Métodos genéricos: permite que o programador defina, com uma única declaração de método, um conjunto de métodos relacionados Os genéricos também fornecem segurança de tipo em tempo de compilação, permitindo a detecção de tipos inválidos em tempo de compilação

1) Escrever um método genérico para ordenar um objeto array e então invocar esse mesmo método com arrays de Integer, arrays de Double, arrays de String para ordenar os elementos no array.

2) Permitir ao compilador realizar uma verificação de tipo para assegurar que o array passado para o método de ordenação contenha elementos do mesmo tipo.

3) Escrever uma única classe Stack genérica que manipulasse uma pilha de objetos e instanciasse objetos Stack em uma pilha de Integer, uma pilha de Double, uma pilha de String, etc. Obs: O compilador realizaria a verificação de tipo para assegurar que a estrutura Stack armazena elementos do mesmo tipo.

Métodos sobrecarregados são bastante utilizados para realizar operações semelhantes em tipos diferentes de dados Ex: Utilização de três métodos printarray sobrecarregados para imprimir um array de tipos diferentes.

Método OverloadedMethods.printArray para imprimir um array de Integer public static void printarray( Integer[] inputarray ) { // exibe elementos do array for ( Integer element : inputarray ) System.out.printf( "%s ", element ); System.out.println(); } // fim do método printarray

Método OverloadedMethods.printArray para imprimir um array de Double public static void printarray( Double[] inputarray ) { // exibe elementos do array for ( Double element : inputarray ) System.out.printf( "%s ", element ); System.out.println(); } // fim do método printarray

Método OverloadedMethods.printArray para imprimir um array de Character public static void printarray( Character[] inputarray ) { // exibe elementos do array for ( Character element : inputarray ) System.out.printf( "%s ", element ); System.out.println(); } // fim do método printarray

Quando o compilador encontra uma chamada de método, ele sempre tenta localizar uma declaração de método com o mesmo nome de método e parâmetros que correspondam aos tipos de argumento da chamada No exemplo, cada chamada a printarray corresponde exatamente a uma das declarações desse método

... printarray( integerarray );... O compilador determina o tipo do argumento integerarray (ie, Integer[]) e tenta localizar um método chamado printarray que especifica um único parâmetro Integer[]

Método OverloadedMethods.main public static void main( String args[] ) { // cria arrays de Integer, Double e Character Integer[] integerarray = { 1, 2, 3, 4, 5, 6 }; Double[] doublearray = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 }; Character[] characterarray = { 'H', 'E', 'L', 'L', 'O' }; System.out.println( "Array integerarray contem:" ); printarray( integerarray ); // passa um array de Integers System.out.println( "\narray doublearray contem:" ); printarray( doublearray ); // passa um array Doubles System.out.println( "\narray characterarray contem:" ); printarray( characterarray ); // passa um array de Characters } // fim de main

Saída do programa: Array integerarray contem: 1 2 3 4 5 6 Array doublearray contem: 1.1 2.2 3.3 4.4 5.5 6.6 7.7 Array characterarray contem: H E L L O

Nesse exemplo, os tipos de elementos dos arrays aparecem em: Nos cabeçalhos dos métodos public static void printarray( Integer[] inputarray ) public static void printarray( Double[] inputarray ) public static void printarray( Character[] inputarray) Nas instruções for for ( Integer element : inputarray ) for ( Double element : inputarray ) for ( Character element : inputarray )

Se os tipos dos elementos em cada método fossem substituídos por um nome de tipo genérico E, então os três métodos de impressão seriam iguais a: public static <E> void printarray( E[] inputarray){ // exibe elementos do array for ( E element : inputarray ) System.out.printf( "%s ", element ); System.out.println(); } // fim do método printarray

Ex: métodos de impressão para arrays de tipos diferentes Utilizando um tipo genérico, é possível declarar um método printarray que pode exibir as representações string dos elementos de qualquer array que contém objetos public static <E> void printarray( E[] inputarray ){ // exibe elementos do array for ( E element : inputarray ) System.out.printf( "%s ", element ); System.out.println(); } // fim do método printarray

Ex: métodos de impressão para arrays de tipos diferentes O especificador de formato %s pode ser utilizado para gerar saída de qualquer objeto de representação de string método tostring é chamado implicitamente public static <E> void printarray( E[] inputarray ){ // exibe elementos do array for ( E element : inputarray ) System.out.printf( "%s ", element ); System.out.println(); } // fim do método printarray

Se as operações realizadas por métodos sobrecarregados forem idênticas para cada tipo de argumento, esses métodos podem ser codificados por métodos genéricos. Representação mais compacta e conveniente Pode-se escrever uma única declaração de método genérico que pode ser chamada com argumentos de tipos diferentes.

Tradução em tempo de compilação: Com base nos tipos dos argumentos passados para o método genérico, o compilador trata cada chamada do método de forma apropriada.

Implementando o método printarray genérico, as chamadas a esse método e as saídas do programa permanecem as mesmas. demonstra o poder expressivo dos genéricos

Todas as declarações de métodos genéricos têm uma seção de parâmetros de tipos, delimitada por colchetes angulares (ex, <E>) que precedem o tipo de retorno do método Cada seção de parâmetros de tipos contém um ou mais parâmetros de tipos, separados por vírgulas Um parâmetro de tipo (também conhecido como variável de tipo) é um identificador que especifica um nome genérico do tipo

Os parâmetros de tipo na declaração de um método genérico podem ser utilizados para especificar: o tipo de retorno tipos de parâmetros tipos de variáveis locais Parâmetros de tipo atuam também como marcadores de lugar para os tipos dos argumentos passados ao método genérico, conhecidos como argumentos de tipos reais

Declaração de métodos genéricos O corpo de um método genérico é declarado como o de qualquer outro método Os parâmetros de tipo podem representar somente tipos por referência não tipos primitivos, como int, double e char Os nomes dos parâmetros de tipo por toda a declaração do método devem corresponder àqueles declarados na seção de parâmetro de tipo

Na instrução for, element é declarado como tipo E, que corresponde ao parâmetro de tipo (E), declarado no cabeçalho do método public static <E> void printarray( E[] inputarray ){ // exibe elementos do array for ( E element : inputarray ) System.out.printf( "%s ", element ); System.out.println(); } // fim do método printarray

Declaração de métodos genéricos Um parâmetro de tipo pode ser declarado somente uma vez na seção de parâmetro de tipo, mas pode aparecer mais de uma vez na lista de parâmetros do método Ex: public static <E> void printtwoarrays(e[] array1, E[] array2) Os nomes de parâmetros de tipo não precisam ser únicos entre diferentes métodos genéricos

Declaração de métodos genéricos - Exemplo A seção de parâmetro de tipo do método printarray, declara o parâmetro de tipo E como o marcador de lugar para o tipo de elemento do array que o método enviará para a saída public static <E> void printarray( E[] inputarray ){ // exibe elementos do array for ( E element : inputarray ) System.out.printf( "%s ", element ); System.out.println(); } // fim do método printarray

Declaração de métodos genéricos - Exemplo A instrução for também utiliza E como o tipo de elemento public static <E> void printarray( E[] inputarray ){ // exibe elementos do array for ( E element : inputarray ) System.out.printf( "%s ", element ); System.out.println(); } // fim do método printarray

Declaração de métodos genéricos É recomendável que parâmetros de tipo sejam especificados como letras maiúsculas individuais Em geral, um parâmetro de tipo que representa o tipo de um elemento em um array (ou em outra estrutura de dados) é nomeado E, que representa elemento

Quando o compilador encontra a chamada printarray( integerarray), ele primeiro determina o tipo do argumento integerarray (ie, Integer[]) e tenta encontrar um método printarray com um único parâmetro desse tipo. Não há tal método nesse exemplo! public static void main( String args[] ) { Integer[] integerarray = { 1, 2, 3, 4, 5, 6 }; Double[] doublearray = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 }; Character[] characterarray = { 'H', 'E', 'L', 'L', 'O' }; System.out.println( "Array integerarray contem:" ); printarray( integerarray ); // passa um array de Integers } // fim de main

Métodos genéricos- Tradução em tempo de compilação Em seguida, o compilador verifica que há um método genérico printarray que especifica um parâmetro de array individual, e utiliza o parâmetro de tipo para representar o tipo de elemento do array public static void main( String args[] ) { Integer[] integerarray = { 1, 2, 3, 4, 5, 6 }; Double[] doublearray = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 }; Character[] characterarray = { 'H', 'E', 'L', 'L', 'O' }; System.out.println( "Array integerarray contem:" ); printarray( integerarray ); // passa um array de Integers } // fim de main

Métodos genéricos- Tradução em tempo de compilação O compilador também determina se as operações no corpo do método genérico podem ser aplicadas a elementos do tipo armazenado no argumento do array Quando o compilador traduz o método genérico em bytecode Java, ele remove a seção de parâmetros de tipo e substitui os parâmetros de tipo por tipos reais Esse processo é chamado de erasure

Métodos genéricos- Tradução em tempo de compilação Por padrão, todos os tipos genéricos são substituídos pelo tipo Object public static void printarray( Object[] inputarray ) { // exibe elementos do array for ( Object element : inputarray ) System.out.printf( "%s ", element ); System.out.println(); } // fim do método printarray

O conceito de uma estrutura de dados, como uma pilha, pode ser entendido independentemente do tipo que ela manipula Classes genéricas fornecem um meio de descrever o conceito de uma pilha (ou de qualquer outra classe) de uma maneira independente do tipo É possível, então, instanciar objetos específicos de uma classe genérica

Em tempo de compilação, o compilador Java garante a segurança de tipo do seu código utiliza técnicas de erasure para permitir que o código do seu cliente interaja com a classe genérica

Uma classe Stack genérica poderia ser a base para criar várias classes Stack, por exemplo: Stack de Double Stack de Integer Stack de Character Essas classes são conhecidas como classes parametrizadas ou tipos parametrizados porque aceitam um ou mais parâmetros

Lembre-se que parâmetros de tipo só representam tipos por referência a classe genérica Stack não pode instanciada com tipos primitivos Entretanto, é possível instanciar uma Stack que armazena objetos das classes empacotadoras Java e permitir que Java utilize o autoboxing para converter os valores primitivos em objetos

A declaração de uma classe genérica se parece com a declaração de uma nãogenérica, exceto que o nome da classe é seguido por uma seção de parâmetros de tipo public class Stack< E > { private final int size; // número de elementos na pilha private int top; // localização do elemento superior private E[] elements; // array que armazena elementos na pilha //...

O parâmetro de tipo E representa o tipo de elemento que a Stack manipulará O parâmetro de tipo E é utilizado por toda declaração da classe para representar o tipo do elemento public class Stack< E > { //... private final int size; // número de elementos na pilha private int top; // localização do elemento superior private E[] elements; // array que armazena elementos na pilha

Declaração de classes genéricas A classe Stack declara a variável elements como um array do tipo E Esse array armazenará os elementos da Stack Como criar esse array? public class Stack< E > { //... private final int size; // número de elementos na pilha private int top; // localização do elemento superior private E[] elements; // array que armazena elementos na pilha

Declaração de classes genéricas Não é permito usar parâmetros de tipo em expressões de criação de arrays porque este parâmetro (no caso, E) não estará disponível em tempo de execução Solução: criar um array do tipo Object e fazer uma coerção na referência retornada por new para o tipo E[] elements = ( E[] ) new Object[ size ]; // cria o array

Declaração de classes genéricas - Método push.stack Exemplo // insere o elemento na pilha; se bem-sucedido retorna true; // caso contrário, lança uma FullStackException public void push( E pushvalue ) { if ( top == size - 1 ) // se a pilha estiver cheia throw new FullStackException( String.format( "Stack is full, cannot push %s", pushvalue ) ); elements[ ++top ] = pushvalue; // insere pushvalue na Stack } // fim do método push

Método pop.stack // retorna o elemento superior se não estiver vazia; do contrário lança uma EmptyStackException public E pop() { Declaração de classes genéricas - if ( top == -1 ) // se pilha estiver vazia throw new EmptyStackException( "Stack is empty, cannot pop" ); return elements[ top-- ]; // remove e retorna o elemento superior da Stack } // fim do método pop Exemplo