Você está na página 1de 259

MANUAL DO CURSO MÓDULO DE LICENCIATURA EM

Gestão de Sistemas de Informação

Programação
Avançada em JAVA
2º ANO : Desenvolvimento e Mudança
Organizacional

CÓDIGO ISCED1-GSI 7
GSITOTAL HORAS/ 1 100
SEMESTRE
CRÉDITOS (SNATCA) 4
NÚMERO DE TEMAS 5
UNIISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em
Java

Direitos de autor (copyright)


Este manual é propriedade da Universidade Aberta Isced (UNISCED), e contém reservados
todos os direitos. É proibida a duplicação ou reprodução parcial ou total deste manual, sob
quaisquer formas ou por quaisquer meios (electrónicos, mecânico, gravação, fotocópia ou
outros), sem permissão expressa de entidade editora (Instituto Superior deCiências e Educação
a Distância (ISCED).
A não observância do acima estipulado o infractor é passível a aplicação de processos judiciais
em vigor no País.

Universidade Aberta Isced (Unisced)


Vice-Reitoria Academica
Rua Dr. Almeida Lacerda, No 212 Ponta - Gêa
Beira - Moçambique
Telefone: +258 23 323501
Cel: +258 82 3055839
Fax: 23323501
E-mail:direcção@unisced.edu.mz

Website: www.isced.edu.mz

i
UNIISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em
Java

Universidade Aberta Isced (UNISCED) agradece a colaboração dosseguintes indivíduos e


instituições na elaboração deste manual:

Autor Jorge Paulino Boane

Coordenação Direcção Académica


Design Universidade Aberta Isced (UNISCED)
Financiamento e Logística Instituto Africano de Promoção da Educação a Distância
Revisão Científica e (IAPED)
Linguística XXXXX
Ano de Publicação 2022
Local de Publicação ISCED – BEIRA

ii
UNIISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em
Java

Índice
Visão geral 1
Benvindo à Disciplina/Módulo Programação Avançada em Java .................................... 1
Objetivos do Módulo ............................................................................................... 1
Quem deveria estudar este módulo ................................................................................... 1
Como está estruturado este módulo .................................................................................. 2
Ícones de atividades .......................................................................................................... 3
Habilidades de estudo ....................................................................................................... 3
Precisa de apoio? .............................................................................................................. 5
Tarefas (avaliação e auto-avaliação) ................................................................................. 6
Avaliação .......................................................................................................................... 6

TEMA – I: INTRODUÇÃO À PROGRAMAÇÃO ORIENTADA A OBJETOS. 9


Unidade temática 1.1: Classe e objeto .............................................................................. 9
Introdução ................................................................................................................ 9
Classe e Objeto ...................................................................................................... 10
Diferença entre classe e Objeto ............................................................................. 11
Sumário ................................................................................................................. 12
Exercícios de autoavaliação .................................................................................. 12
Perguntas ...................................................................................................... 12
Respostas: .................................................................................................... 13
Exercícios para avaliação ...................................................................................... 13
Unidade temática 1.2: Processo de desenvolvimento de aplicações com orientação a
objetos ............................................................................................................................. 15
Introdução ....................................................................................................................... 15
Passos para programar orientado a objetos ........................................................... 15
Sumário ................................................................................................................. 16
Exercícios de autoavaliação .................................................................................. 16
Perguntas ...................................................................................................... 16
Respostas: .................................................................................................... 17
Exercícios para avaliação ...................................................................................... 17
Unidade temática 1.3: Elementos de uma classe de objetos ........................................... 18
Introdução ....................................................................................................................... 18
Elementos da classe de objetos ............................................................................. 19
Atributos ...................................................................................................... 20
O construtor ................................................................................................. 20
Os métodos................................................................................................... 20

iii
UNIISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em
Java

O uso da palavra reservada “this” em classes de objetos ................... 21


Pacotes e Importação .......................................................................... 21
Sumário ................................................................................................................. 22
Exercícios de autoavaliação .................................................................................. 23
Perguntas ...................................................................................................... 23
Respostas: .................................................................................................... 23
Exercícios para avaliação ...................................................................................... 24
Unidade temática 1.4: Instanciação e manipulação de objetos ....................................... 25
Introdução ....................................................................................................................... 25
Instanciação e Manipulação de instância .............................................................. 26
Sumário ................................................................................................................. 27
Exercícios de autoavaliação .................................................................................. 28
Perguntas ...................................................................................................... 28
Respostas: .................................................................................................... 28
Exercícios para avaliação ...................................................................................... 29
Exercícios do tema .......................................................................................................... 30
Exercícios de autoavaliação .................................................................................. 30
Perguntas ...................................................................................................... 30
Respostas...................................................................................................... 31
Exercícios para avaliação ...................................................................................... 35
Referências Bibliográficas .............................................................................................. 36

TEMA – II: OS PILARES DA PROGRAMAÇÃO ORIENTADA A OBJETOS. ENCAPSULAMENTO,


POLIMORFISMO E ABRASTRAÇÃO. 38
Unidade temática 2.1: Encapsulamento .......................................................................... 38
Introdução ....................................................................................................................... 38
Definição ............................................................................................................... 38
Encapsulamento na resolução de problemas de inconsistência ............................. 39
Getters e Setters ........................................................................................... 43
Sumário ................................................................................................................. 45
Exercícios de autoavaliação .................................................................................. 46
Perguntas ...................................................................................................... 46
Respostas: .................................................................................................... 47
Exercícios para avaliação ...................................................................................... 50
Perguntas ...................................................................................................... 50
Unidade temática 2.2. Herança ....................................................................................... 51
Introdução ....................................................................................................................... 51
O Problema ............................................................................................................ 52
Definição ............................................................................................................... 53
Sobreposição/Reescrita(Overriding) de métodos .................................................. 56
Manipulação de objetos de classe com Herança ................................................... 57
Exemplo ............................................................................................... 57
A classe “Object” e reescrita dos seus métodos .................................................... 57
“O toString” ......................................................................................... 58

iv
UNIISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em
Java

“O equals” ............................................................................................ 59
Sumário ................................................................................................................. 60
Exercícios de autoavaliação .................................................................................. 60
Perguntas ...................................................................................................... 60
Respostas: .................................................................................................... 61
Exercícios para avaliação ...................................................................................... 65
Perguntas ...................................................................................................... 65
Unidade temática 2.3: Polimorfismo e abstração. .......................................................... 66
Introdução ....................................................................................................................... 66
O problema ............................................................................................................ 67
Definição ............................................................................................................... 72
Benefícios do polimorfismo .................................................................................. 73
O polimorfismo – a conclusão............................................................................... 76
Classes abstratas e Abstração ................................................................................ 76
Interface ................................................................................................................. 80
Definição de Interface ......................................................................... 84
Exemplo 3 ............................................................................................ 84
Sumário ................................................................................................................. 88
Exercícios de autoavaliação .................................................................................. 89
Perguntas ...................................................................................................... 89
Respostas: .................................................................................................... 89
Exercícios para avaliação ...................................................................................... 90
Perguntas ...................................................................................................... 90
Execícios do Tema .......................................................................................................... 92
Exercios de autoavaliação ..................................................................................... 92
Perguntas ...................................................................................................... 92
Respostas...................................................................................................... 94
Execícios para avaliação...................................................................................... 101
Referências Bibliográficas ............................................................................................ 103

TEMA – III: Persistência de Dados com Streams 104


Unidade temática 3.1: Introdução a “Streams” e persistência de dados ....................... 104
Introdução ............................................................................................................ 104
Streams disponibilizados pelo JAVA .................................................................. 104
Sumário ............................................................................................................... 105
Exercícios de autoavaliação ................................................................................ 106
Perguntas .................................................................................................... 106
Respostas: .................................................................................................. 106
Exercícios para avaliação .................................................................................... 106
Unidade temática 3.2: FileReader e Filewriter ............................................................. 107
Introdução ..................................................................................................................... 107
Abrindo um ficheiro de texto para a escrita usando FileWriter .......................... 107
Escrevendo em um ficheiro de texto ................................................................... 109
Abertura de ficheiro de texto para a leitura usando FileReader .......................... 110
Recuperando os dados do ficheiro da ponta-a-ponta........................................... 110

v
UNIISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em
Java Sumário ............................................................................................................... 112
Exercícios de autoavaliação ................................................................................ 113
Perguntas .................................................................................................... 113
Respostas.................................................................................................... 113
Exercícios para avaliação .................................................................................... 114
Unidade temática 3.3 BufferedWriter e BufferedReader ............................................. 116
Introdução ............................................................................................................ 116
Streams “buferizados” (buffered) ........................................................................ 117
Abrindo um ficheiro de texto para a escrita usando BufferedWriter .................. 117
Leitura de dados em ficheiro de texto usando BufferedReader .......................... 118
Problemas envolvendo ficheiros de texto ............................................................ 119
Atualizando um ficheiro de texto ........................................................................ 121
Sumário ............................................................................................................... 123
Exercícios de autoavaliação ................................................................................ 123
Perguntas .................................................................................................... 123
Respostas: .................................................................................................. 125
Exercícios para avaliação .................................................................................... 130
Unidade temática 3.4: FileInputStream e FileOutputStream ........................................ 132
Introdução ..................................................................................................................... 132
Porquê FileOutputStream e FileInputStream ...................................................... 132
Cópia de ficheiro usando FileInputStream e FileOutputStream ......................... 132
Sumário ............................................................................................................... 134
Exercícios de autoavaliação ................................................................................ 135
Perguntas .................................................................................................... 135
Respostas.................................................................................................... 135
Exercícios para avaliação .................................................................................... 136
Unidade temática 3.5. ObjectInputStream E ObjectOutputStream .............................. 138
Introdução ..................................................................................................................... 138
Entendendo o processo de serialização e de-serialização ................................... 138
Processo de escrita de objetos em ficheiro .......................................................... 139
Processo de recuperação de objetos em ficheiro ................................................. 139
Exemplo............................................................................................................... 140
Sumário ............................................................................................................... 143
Exercícios de autoavaliação ................................................................................ 144
Perguntas .................................................................................................... 144
Respostas: .................................................................................................. 144
Exercícios para avaliação .................................................................................... 147
Unidade temática 3.6: Entrada de dados usando a classe Scanner ............................... 149
Introdução ..................................................................................................................... 149
Processo de interação entre o utilizador e os programas ..................................... 149
Inicialização do Scanner e seu fecho ................................................................... 150
Métodos disponibilizado pelo Scanner ................................................................ 150
Interação com o Utilizador usando o Scanner e o PrintWriter ............................ 151
Sumário ............................................................................................................... 152
Exercícios de autoavaliação ................................................................................ 153
Perguntas .................................................................................................... 153
Respostas.................................................................................................... 153

vi
UNIISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em
Java Exercícios para avaliação .................................................................................... 155
Exercícios do tema ........................................................................................................ 157
Exercícios de autoavaliação ................................................................................ 157
Perguntas .................................................................................................... 157
Respostas.................................................................................................... 161
Exercícios para avaliação .................................................................................... 178
Referências Bibliográficas ............................................................................................ 179

TEMA – IV: TIPOS GENÉRCOS(GENERICS) 181


Unidade temática 4.1: Tipos e métodos genéricos ....................................................... 181
Introdução ............................................................................................................ 181
Porquê o uso de Generics? .................................................................................. 181
Definindo um Tipo Genérico .............................................................................. 183
Instanciação e manipulação de classes Genéricas ............................................... 185
Métodos Genéricos .............................................................................................. 187
Sumário ............................................................................................................... 188
Exercícios de autoavaliação ................................................................................ 188
Perguntas .................................................................................................... 188
Respostas.................................................................................................... 188
Exercícios para avaliação .................................................................................... 189
Unidade temática 4.2. Subtipos com tipos genéricos ................................................... 190
Introdução ............................................................................................................ 190
Herança com tipos de dados genéricos ................................................................ 190
Interfaces genéricas e sua implementação ........................................................... 192
Polimorfismo com tipos genéricos ...................................................................... 193
Sumário ............................................................................................................... 194
Exercícios de autoavaliação ................................................................................ 194
Perguntas .................................................................................................... 194
Respostas.................................................................................................... 194
Exercícios para avaliação .................................................................................... 195
Unidade temática 4.3: Mais em volta de Generics ....................................................... 197
Introdução ............................................................................................................ 197
Múltiplos parâmetros em um tipo genérico ......................................................... 197
“Wildcard”........................................................................................................... 198
Quando usar wildcard e quando usar tipos parametrizados ................................ 199
O uso de “extends” com tipos genéricos ............................................................. 200
“Tipos brutos” (Raw Types) ................................................................................ 201
Sumário ............................................................................................................... 202
Exercícios de autoavaliação ................................................................................ 202
Perguntas .................................................................................................... 202
Respostas.................................................................................................... 202
Exercícios para avaliação .................................................................................... 202
Exercícios do tema ........................................................................................................ 205
Exercícios de autoavaliação ................................................................................ 205
Perguntas .................................................................................................... 205
Respostas.................................................................................................... 205

vii
UNIISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em
Java Exercícios para avaliação .................................................................................... 206
Referências Bibliográficas ............................................................................................ 208

TEMA – V: Estudo particular de Coleções Parametrizadas (Collections Framework) 209


Unidade temática 4.1. Introdução ao Collections Framework ...................................... 209
Introdução ............................................................................................................ 209
Uma introdução ao Collections Framework ........................................................ 209
Sumário ......................................................................................................................... 211
Exercícios de autoavaliação .......................................................................................... 211
Perguntas ............................................................................................................. 211
Respostas ............................................................................................................. 212
Exercícios para avaliação .............................................................................................. 212
Unidade temática 5.2. As listas (List) ........................................................................... 213
Introdução ............................................................................................................ 213
A interface List e seus métodos ........................................................................... 214
Implementações da interface List ........................................................................ 216
Instanciação de listas ........................................................................................... 217
Manipulação de listas .......................................................................................... 218
Iteração em listas ................................................................................................. 220
Ordenação de listas .............................................................................................. 221
Polimorfismo com listas ...................................................................................... 223
Sumário ............................................................................................................... 225
Exercícios de autoavaliação ................................................................................ 225
Perguntas .................................................................................................... 225
Respostas.................................................................................................... 226
Exercícios para avaliação .................................................................................... 228
Unidade Temática 5.3. Os Conjuntos (Set) .................................................................. 229
Introdução ............................................................................................................ 229
A interface Set e seus métodos ............................................................................ 229
Implementações da interface Set ...................................................... 231
Criação, Manipulação e Iteração em HashSet ................................... 231
Sumário ............................................................................................................... 232
Exercícios de autoavaliação ................................................................................ 233
Perguntas .................................................................................................... 233
Respostas: .................................................................................................. 233
Exercícios para avaliação .................................................................................... 234
Unidade temática 5.4. Os mapas (Map) ........................................................................ 236
Introdução ............................................................................................................ 236
A interface Map e seus métodos.......................................................................... 236
Implementações da interface Map ....................................................................... 237
Aplicação com Mapas ......................................................................................... 237
Iteração em um Mapa .......................................................................................... 238
Sumário ............................................................................................................... 239
Exercícios de autoavaliação ................................................................................ 239
Perguntas .................................................................................................... 239

viii
UNIISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em
Java Respostas: .................................................................................................. 239
Exercícios para avaliação .................................................................................... 240
Exercícios do tema ........................................................................................................ 242
Exercícios de autoavaliação ................................................................................ 242
Perguntas .................................................................................................... 242
Respostas.................................................................................................... 242
Exercícios de avaliação ....................................................................................... 243
Referências Bibliográficas ............................................................................................ 245

Exercícios de Preparação Erro! Marcador não definido.


Perguntas .......................................................................... Erro! Marcador não definido.
Respostas ......................................................................... Erro! Marcador não definido.

Anexos Erro! Marcador não definido.


Temas de discussão fórum 1 ............................................ Erro! Marcador não definido.
Tema 1: Discussão de conceitos de orientação a objetos ....... Erro! Marcador não
definido.
Tema 2: Análise e desenho aplicações ................... Erro! Marcador não definido.
Tema 3: Identificação de elementos de uma classe Erro! Marcador não definido.
Tema 4: Identificação de problemas no processo de desenvolvimento de
aplicações e proposta de Solução (parte I) ............. Erro! Marcador não definido.
Tema 5: Identificação de problemas no processo de desenvolvimento de
aplicações e proposta de Solução (parte II) ............ Erro! Marcador não definido.
Tema 6: Identificação de problemas no processo de desenvolvimento de
aplicações e proposta de Solução (parte III)........... Erro! Marcador não definido.
Tema 7: Interpretação do código para a perceção de código de terceiros ........ Erro!
Marcador não definido.
Tema 8: Interpretação do código para a manutenção de aplicações ................ Erro!
Marcador não definido.
Tema 09: Concepção de Aplicações (Parte I) ........ Erro! Marcador não definido.
Tema 10: Tema para investigação .......................... Erro! Marcador não definido.
Temas de discussão fórum 2 ............................................ Erro! Marcador não definido.
Tema 1: Caso Sistema de gestão de biblioteca ....... Erro! Marcador não definido.
Tema 2: Caso Sistema de gestão clínica................. Erro! Marcador não definido.
Tema 3: Sistema de Gestão de gestão de agencia de viagens Erro! Marcador não
definido.
Tema 4: Caso Sistema de Gestão de Hotel ............. Erro! Marcador não definido.
Tema 5: Caso Sistema de Gestão de Condomínio . Erro! Marcador não definido.
Tema 6: Caso Sistema de Gestão de recursos partilhados...... Erro! Marcador não
definido.
Tema 7: Caso Sistema de Gestão de Stock ............ Erro! Marcador não definido.
Tema 8: Caso Sistema integrado de emissão de documentos para o cidadão ..Erro!
Marcador não definido.
Tema 09: Caso Sistema de Gestão Acadêmica ...... Erro! Marcador não definido.
Tema 10: Caso Sistema de Gestão de Licenciamento de Transportadores ...... Erro!
Marcador não definido.

ix
UNIISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em
Java

Temas para trabalho de Campo........................................ Erro! Marcador não definido.


Tema 1: Sistema controle de consumo de eletricidade .......... Erro! Marcador não
definido.
Tema 2: Sistema de gestão de empréstimo bancário .............. Erro! Marcador não
definido.
Tema 3: Sistema de gestão de biblioteca ................ Erro! Marcador não definido.
Tema 4: Sistema de licenciamento de transportadores ........... Erro! Marcador não
definido.
Tema 5: Sistema de gestão de seguros ................... Erro! Marcador não definido.
Tema 6: Sistema de suporte bancário ..................... Erro! Marcador não definido.
Tema 7: Sistema de gestão de Vendas ................... Erro! Marcador não definido.
Tema 8: Sistema de gestão de Farmácia ................. Erro! Marcador não definido.
Tema 09: Sistema de gestão de Stock .................... Erro! Marcador não definido.
Tema 10: Sistema controle de consumo de água.... Erro! Marcador não definido.

x
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Visão geral

Benvindo à Disciplina/Módulo Programação


Avançada em Java

Objetivos do Módulo
Ao terminar o estudo deste módulo de Programação Avançada em
Java o estudante deverá ser capaz de: Compreender e Aplicar os
Pilares de Programação Orientada a objectos (encapsulamento,
abstração e polimorfismo), na conceção de Aplicações baseadas em
Java. Para tal deverá:

▪ Compreender os conceitos básicos de orientação a objectos,


nomeadamente: classe de objectos, instanciação e manipulação de
objectos.
▪ Compreender e aplicar os conceitos avançados de orientação a
Objetivos objectos, nomeadamente: herança, classes abstratas e interfaces;
Específicos
▪ Construir aplicações em java que estejam baseadas nos 3 pilares de
programação orientada à java, nomeadamente: encapsulamento,
abstração e polimorfismo.

Quem deveria estudar este módulo

Este Módulo foi concebido para estudantes do 4º ano do curso de


Gestão de Sistemas de Informação do ISCED. Poderá ocorrer,
contudo, que haja leitores que queiram se atualizar e consolidar
seus conhecimentos nesta disciplina, esses serão bem-vindos, não
sendo necessário para tal se inscrever. Mas poderá adquirir o
manual.

1
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Como está estruturado este módulo

Este módulo de Programação Avançada em Java, para estudantes


do 4º ano do curso de licenciatura em Gestão de Sistemas de
Informação, à semelhança dos restantes do ISCED, está estruturado
como se segue:

Páginas introdutórias
▪ Um índice completo.
▪ Uma visão geral detalhada dos conteúdos do módulo,
resumindo os aspetos-chave que você precisa conhecer para
melhor estudar. Recomendamos vivamente que leia esta secção
com atenção antes de começar o seu estudo, como componente
de habilidades de estudos.

Conteúdo desta Disciplina / módulo


Este módulo está estruturado em Temas. Cada tema, por sua vez
comporta certo número de unidades temáticas ou simplesmente
unidades. Cada unidade temática se caracteriza por conter uma
introdução, objetivos, conteúdos.
No final de cada unidade temática ou do próprio tema, são
incorporados antes o sumário, exercícios de autoavaliação, só
depois é que aparecem os exercícios de avaliação.
Os exercícios de avaliação têm as seguintes características: puros
exercícios teóricos/Práticos, Problemas não resolvidos e
actividades práticas, incluído estudo de caso.

Outros recursos
A equipa dos académicos e pedagogos do ISCED, pensando em si,
num cantinho, recôndito deste nosso vasto Moçambique e cheio de
dúvidas e limitações no seu processo de aprendizagem, apresenta
uma lista de recursos didáticos adicionais ao seu módulo para você
explorar. Para tal o ISCED disponibiliza na biblioteca do seu centro
de recursos mais material de estudos relacionado com o seu curso
como: Livros e/ou módulos, CD, CD-ROOM, DVD. Para além deste
material físico ou eletrónico disponível na biblioteca, pode ter
acesso a Plataforma digital moodle para alargar mais ainda as
possibilidades dos seus estudos.

2
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Autoavaliação e Tarefas de avaliação


Tarefas de autoavaliação para este módulo encontram-se no final
de cada unidade temática e de cada tema. As tarefas dos exercícios
de autoavaliação apresentam duas características: primeiro
apresentam exercícios resolvidos com detalhes. Segundo,
exercícios que mostram apenas respostas.
Tarefas de avaliação devem ser semelhantes às de autoavaliação
mas sem mostrar os passos e devem obedecer o grau crescente de
dificuldades do processo de aprendizagem, umas a seguir a outras.
Parte das tarefas de avaliação será objeto dos trabalhos de campo
a serem entregues aos tutores/docentes para efeitos de correção e
subsequentemente nota. Também constará do exame do fim do
módulo. Pelo que, caro estudante, fazer todos os exercícios de
avaliação é uma grande vantagem.

Comentários e sugestões
Use este espaço para dar sugestões valiosas, sobre determinados
aspetos, quer de natureza científica, quer de natureza didático-
Pedagógica, etc, sobre como deveriam ser ou estar apresentadas.
Pode ser que graças as suas observações que, em gozo de confiança,
classificamo-las de úteis, o próximo módulo venha a ser melhorado.

Ícones de atividades

Ao longo deste manual irá encontrar uma série de ícones nas


margens das folhas. Estes ícones servem para identificar diferentes
partes do processo de aprendizagem. Podem indicar uma parcela
específica de texto, uma nova atividade ou tarefa, uma mudança de
atividade, etc.

Habilidades de estudo

O principal objetivo deste campo é o de ensinar aprender a


aprender. Aprender aprende-se.
Durante a formação e desenvolvimento de competências, para
facilitar a aprendizagem e alcançar melhores resultados, implicará
empenho, dedicação e disciplina no estudo. Isto é, os bons
resultados apenas se conseguem com estratégias eficientes e
eficazes. Por isso é importante saber como, onde e quando estudar.
Apresentamos algumas sugestões com as quais esperamos que caro
estudante possa rentabilizar o tempo dedicado aos estudos,
procedendo como se segue:

3
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

1º praticar a leitura. Aprender a Distância exige alto domínio de


leitura.
2º fazer leitura diagonal aos conteúdos (leitura corrida).
3º voltar a fazer leitura, desta vez para a compreensão e assimilação
crítica dos conteúdos (ESTUDAR).
4º fazer seminário (debate em grupos), para comprovar se a sua
aprendizagem confere ou não com a dos colegas e com o padrão.
5º fazer TC (Trabalho de Campo), algumas actividades práticas ou
as de estudo de caso se existirem.
IMPORTANTE: em observância ao triângulo modo-espaço-tempo,
respetivamente como, onde e quando...estudar, como foi referido
no início deste item, antes de organizar os seus momentos de
estudo reflita sobre o ambiente de estudo que seria ideal para si:
Estudo melhor em casa/biblioteca/café/outro lugar? Estudo melhor
à noite/de manhã/de tarde/fins-de-semana/ao longo da semana?
Estudo melhor com música/num sítio sossegado/num sítio
barulhento!? Preciso de intervalo em cada 30 minutos, em cada
hora, etc.
É impossível estudar numa noite tudo o que devia ter sido estudado
durante um determinado período de tempo; deve estudar cada
ponto da matéria em profundidade e passar só ao seguinte quando
achar que já domina bem o anterior.
Privilegia-se saber bem (com profundidade) o pouco que puder ler
e estudar, que saber tudo superficialmente! Mas a melhor opção é
juntar o útil ao agradável: saber com profundidade todos
conteúdos de cada tema, no módulo.
Dica importante: não recomendamos estudar seguidamente por
tempo superior a uma hora. Estudar por tempo de uma hora
intercalado por 10 (dez) a 15 (quinze) minutos de descanso (chama-
se descanso à mudança de actividades). Ou seja, que durante o
intervalo não se continuar a tratar dos mesmos assuntos das
actividades obrigatórias.
Uma longa exposição aos estudos ou ao trabalho intelectual
obrigatório pode conduzir ao efeito contrário: baixar o rendimento
da aprendizagem. Por que o estudante acumula um elevado volume
de trabalho, em termos de estudos, em pouco tempo, criando
interferência entre os conhecimentos, perde sequência lógica, por
fim ao perceber que estuda tanto, mas não aprende, cai em
insegurança, depressão e desespero, por se achar injustamente
incapaz!

4
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Não estude na última da hora; quando se trate de fazer alguma


avaliação. Aprenda a ser estudante de facto (aquele que estuda
sistematicamente), não estudar apenas para responder a questões
de alguma avaliação, mas sim estude para a vida, sobre tudo,estude
pensando na sua utilidade como futuro profissional, na áreaem que
está a se formar.
Organize na sua agenda um horário onde define a que horas e que
matérias deve estudar durante a semana; Face ao tempo livre que
resta, deve decidir como o utilizar produtivamente, decidindo
quanto tempo será dedicado ao estudo e a outras actividades.
É importante identificar as ideias principais de um texto, pois será
uma necessidade para o estudo das diversas matérias que compõem
o curso: A colocação de notas nas margens pode ajudar a estruturar
a matéria de modo que seja mais fácil identificar as partes que está a
estudar e Pode escrever conclusões, exemplos, vantagens,
definições, datas, nomes, pode também utilizar a margem para
colocar comentários seus relacionados com o que está a ler; a melhor
altura para sublinhar é imediatamente a seguir à compreensão do
texto e não depois de uma primeira leitura; Utilizar o dicionário
sempre que surja um conceito cujo significado não conhece ou não
lhe é familiar;

Precisa de apoio?

Caro estudante temos a certeza que por uma ou por outra razão, o
material de estudos impresso, lhe pode suscitar algumas dúvidas
como falta de clareza, alguns erros de concordância, prováveis
erros ortográficos, falta de clareza, fraca visibilidade, página
trocada ou invertidas, etc). Nestes casos, contacte os serviços de
atendimento e apoio ao estudante do seu Centro de Recursos (CR),
via telefone, sms, E-mail, se tiver tempo, escreva mesmo uma carta
participando a preocupação.
Uma das atribuições dos Gestores dos CR e seus assistentes
(Pedagógico e Administrativo), é a de monitorar e garantir a sua
aprendizagem com qualidade e sucesso. Dai a relevância da
comunicação no Ensino a Distância (EAD), onde o recurso as TIC se
tornam incontornável: entre estudantes, estudante – Tutor,
estudante – CR, etc.
As sessões presenciais são um momento em que você caro
estudante, tem a oportunidade de interagir fisicamente com staff
do seu CR, com tutores ou com parte da equipa central do ISCED
indigitada para acompanhar as suas sessões presenciais. Neste

5
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

período pode apresentar dúvidas, tratar assuntos de natureza


pedagógica e/ou administrativa.
O estudo em grupo, que está estimado para ocupar cerca de 30%
do tempo de estudos a distância, é muita importância, na medida
em que lhe permite situar, em termos do grau de aprendizagem
com relação aos outros colegas. Desta maneira ficará a saber se
precisa de apoio ou precisa de apoiar aos colegas. Desenvolver
hábito de debater assuntos relacionados com os conteúdos
programáticos, constantes nos diferentes temas e unidade
temática, no módulo.

Tarefas (avaliação e auto-avaliação)

O estudante deve realizar todas as tarefas (exercícios, actividades e


auto−avaliação), contudo nem todas deverão ser entregues, mas é
importante que sejam realizadas. As tarefas devem ser entregues
duas semanas antes das sessões presenciais seguintes.
Para cada tarefa serão estabelecidos prazos de entrega, e o não
cumprimento dos prazos de entrega, implica a não classificação do
estudante. Tenha sempre presente que a nota dos trabalhos de
campo conta e é decisiva para ser admitido ao exame final da
disciplina/módulo.
Os trabalhos devem ser entregues ao Centro de Recursos (CR) e os
mesmos devem ser dirigidos ao tutor/docente.
Podem ser utilizadas diferentes fontes e materiais de pesquisa,
contudo os mesmos devem ser devidamente referenciados,
respeitando os direitos do autor.
O plágio1 é uma violação do direito intelectual do(s) autor(es). Uma
transcrição à letra de mais de 8 (oito) palavras do testo de um autor,
sem o citar é considerado plágio. A honestidade, humildade
científica e o respeito pelos direitos autorais devem caracterizar a
realização dos trabalhos e seu autor (estudante do ISCED).

Avaliação

Muitos perguntam: como é possível avaliar estudantes à distância,


estando eles fisicamente separados e muito distantes do

1
Plágio - copiar ou assinar parcial ou totalmente uma obra literária, propriedade
intelectual de outras pessoas, sem prévia autorização.

6
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

docente/tutor! Nós dissemos: sim é muito possível, talvez seja uma


avaliação mais fiável e consistente.
Você será avaliado durante os estudos à distância que contam com
um mínimo de 90% do total de tempo que precisa de estudar os
conteúdos do seu módulo. Quando o tempo de contacto presencial
conta com um máximo de 10%) do total de tempo do módulo. A
avaliação do estudante consta detalhada do regulamentado de
avaliação.
Os trabalhos de campo por si realizados, durante estudos e
aprendizagem no campo, pesam 25% e servem para a nota de
frequência para ir aos exames.
Os exames são realizados no final da cadeira disciplina ou modulo e
decorrem durante as sessões presenciais. Os exames pesam no
mínimo 75%, o que adicionado aos 25% da média de frequência,
determinam a nota final com a qual o estudante conclui a cadeira.
A nota de 10 (dez) valores é a nota mínima de conclusão da cadeira.
Nesta cadeira o estudante deverá realizar pelo menos 2 (dois)
trabalhos e 1 (um) (exame).
Algumas actividades práticas, relatórios e reflexões serão utilizados
como ferramentas de avaliação formativa.
Durante a realização das avaliações, os estudantes devem ter em
consideração a apresentação, a coerência textual, o grau de
cientificidade, a forma de conclusão dos assuntos, as
recomendações, a identificação das referências bibliográficas
utilizadas, o respeito pelos direitos do autor, entre outros.
Os objectivos e critérios de avaliação constam do Regulamento de
Avaliação.

7
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

TEMA – I: INTRODUÇÃO À PROGRAMAÇÃO ORIENTADA A OBJETOS.

Unidade temática 1.1: Classe e Objeto


Unidade temática 1.2: Processo de Desenvolvimento de Aplicações
com Orientação a objetos
Unidade temática 1.3: Elementos de uma Classe de Objetos
Unidade temática 1.4: Instanciação e Manipulação de Objetos
Unidade temática 1.5: Exercícios deste tema

Unidade temática 1.1: Classe e objeto

Introdução
Nas disciplinas de programação que precedem a disciplina de
Programação avançada (P1 e P2) foram introduzidos os conceitos
básicos da programação orientada a objetos. Sem dúvida ficou claro
que este paradigma de programação facilita, em muito, a vida do
programador.
Usando a Programação orientada a objetos (POO), os programas
tornam-se legíveis e fáceis de manter devido à flexibilidade que se tem
em introduzir modificações no código.
Nesta disciplina serão introduzidos conceitos avançados relacionados
com a técnica de programação orientada a objetos, estes, são conceitos
que quando bem aplicados trazem ganhos significativos ao processo de
desenvolvimento e manutenção de aplicações; estes são os chamados,
pilares da orientação a objetos! São eles: (1) Encapsulamento; (2)
Abstração e (3) Polimorfismo.
Porém, antes de avançar e aprofundar nestes conceitos, vamos fazer
uma breve revisão dos conceitos básicos de programação orientada a
objetos. Começaremos por contextualizar o conceito “objeto” em
programação bem como o conceito de classe de objetos. Mais tarde
será apresentada a abordagem aplicada em programação orientada a
objetos para depois debruçar-se um pouco mais nos elementos que
compõe uma classe de objetos. Para terminar apresenta-se os
mecanismos de aplicação de classe de objetos bem como a
manipulação dos elementos do objeto.
Ao completar esta unidade, você deverá ser capaz de:

▪ Compreender: os conceitos “classe” e “objeto” na programação


orientada a objeto;
▪ Definir: os conceitos “classe” e “objeto”;
Objectivos
▪ Diferenciar: os conceitos “classe” e “objeto”.

9
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

específicos

Classe e Objeto
A programação orientada a objetos procura aproximar o código à
realidade que nos rodeia. Quando olhamos ao nosso redor vemos
objetos, esses objetos têm suas características, sua forma de estar e
propósitos específicos. No mundo real, os objetos encontram-se
agrupados em classes ou famílias de objetos; por exemplo:
eletrodomésticos, automóveis, telemóveis, etc.
Uma classe de objetos descreve as características comuns bem como as
habilidades (ou propósito) de cada objeto por ela representada. Na
figura 1 temos um exemplo de representação de classe de objetos. Note
que aqui lista-se algumas possíveis características que podem interessar
para descrever a classe de objetos em causa, o automóvel.

Figura 1: Exemplo de uma classe objeto e Listagem de suas características

Em programação orientada a objetos, os dados são agrupados em


estruturas chamadas objetos. Um objeto é uma coleção de dados
relacionados, os quais descrevem uma entidade específica. Estes dados
são manipulados de forma controlada a nível do “objeto”. A
manipulação de dados do objeto é feita por meio de rotinas específicas
definidas para esse propósito.
Cada objeto pertence a uma classe (família) a qual descreve as
características e habilidades dos objetos daquela família. Uma classe de
objetos é representada em forma textual em ficheiro do tipo “.java”
onde são descritas as características dos objetos por ela representada;
estas características são descritas em

10
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

forma de variáveis, as chamadas variáveis de instância ou atributos da


classe. No exemplo apresentado na figura 1, algumas características
comuns a todos os automóveis seriam: marca, modelo, ano fabrico,
número de registo, etc.
Além das características, uma classe de objetos define as “habilidades”
dos objetos, isto é, aquilo que os objetos [daquela classe] “podem fazer”
(o propósito para o qual existem). No exemplo do automóvel, algumas
habilidades seriam por exemplo: mover-se de um ponto para outro,
travar, transportar, iluminar, etc.
Em POO as “habilidades” dos objetos são representadas em forma de
métodos (funções); trata-se de rotinas que manipulam os dados do
objeto, isto é, modificam o estado do objeto!
Considere por exemplo o objeto abstrato “Conta Bancária”. Uma Conta
Bancária pode ser descrita pelo número, titular e saldo; estas são
algumas características da Conta Bancária. As habilidades da Conta
Bancária seriam, por exemplo: depositar, transferir e levantar dinheiro.
Neste caso, as habilidades correspondem às operações sobre a Conta.
Cada uma das operações mencionadas, modifica o estado da conta,
neste caso em concreto o saldo da Conta.
A abordagem de modificar os dados a partir de rotinas próprias do
objeto, garante segurança e consistência de dados visto que os dados
são manipulados de forma controlada pelo próprio objeto uma vez que
cada objeto “sabe melhor mexer com os seus próprios dados”.

Diferença entre classe e Objeto


Enquanto a classe descreve as características e habilidades de objetos
pertencentes a um grupo ou família, o objeto é uma ocorrência
específica de uma classe! Por exemplo, quando pensamos em
automóvel no geral imaginamos a marca, o modelo, o ano de fabrico, o
número de registo e talvez outros atributos que sejam relevantes para
descrever o automóvel. Mas quando pensamos em um automóvel
específico (concreto), como por exemplo o automóvel pertencente a
um certo individuo, ou um automóvel que se envolveu em algum
acidente ou talvez um automóvel que foi roubado em uma residência,
aí temos respostas às questões do carro no geral. Por exemplo,
sabemos qual é marca do automóvel (exemplo: Toyota), sabemos qual
é o modelo do automóvel (exemplo: Corolla), sabelos qual é o ano de
fabrico (exemplo: 2003) e também sabemos qual é o número de registo
(exemplo: CZW 985MC). Trata-se, portanto, de uma ocorrência
específica da classe “Automóvel”.
A classe pode ser considerada um “molde” ou “esboço” de objetos. Um
molde é apenas uma representação, uma ideia, ao posso que o objeto
tem uma existência, ele ocupa espaço!

11
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Em POO, a classe é considerada “descritor” do objeto e o objeto


instância dessa classe. Uma instância de objeto tem representação na
memória do computador.
A figura 2, ilustra uma ocorrência específica de um Automóvel.

Figura 2: Ilustração de uma ocorrência da classe "Carro"


Uma única classe pode ter múltiplas ocorrências, isto é, múltiplas
instâncias. Em princípio um objeto pertence a uma e única classe,
embora, graças ao conceito de polimorfismo, ele possa ser considerado
pertencente a múltiplas classes.

Sumário
Nesta Unidade temática 1.1 fizemos a revisão dos conceitos classe e
objeto. Estes são conceitos básicos da programação orientada a objetos
e eles estão intrinsecamente ligados, na medida em que a classe
descreve múltiplos objetos de uma determinada família ou grupo e o
objeto é uma ocorrência específica de uma classe. Ficou claro que
programar usando estes conceitos garante maior consistência e
integridade de dados, visto que os mesmos são manipulados de forma
agrupada e controlada.

Exercícios de autoavaliação
Perguntas
1. Defina os seguintes conceitos classe e objeto.
2. Diferencie os Conceitos Classe e Objeto.
3. Agrupe os seguintes termos em Classe ou Objeto: carro,
avião, acidente de Mbuzine, cabo USB, Sr. Jota-Jota, conta
bancária da primeira dama de Jugoslávia, musica, carro
roubado ontem, único carro do meu vizinho da frente, a

12
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

relva do meu quintal, Mercedes-benz – 57 9 GP, música


“meu amor” do cantor Firiston, céu, ladrão.
4. Em POO o que representa o estado do objeto?
5. Em POO o que modifica o estado de um objeto?
Respostas:
1. Resolução
a) Classe é a representação genérica de um conjunto de
objetos; descreve as características e habilidades
comuns a todos os objetos daquela classe;
b) Objeto é um agrupamento de dados específicos sobre
os quais podem ser executadas operações.
2. Enquanto a classe descreve as caraterísticas e habilidades
genéricas dos objetos, o objeto ou instância é uma
ocorrência específica de uma classe.
3. Classe: carro, avião, musica, carro roubado ontem, ladrão,
cabo USB;
Objeto: acidente de Mbuzine, Sr. Jota-Jota, conta bancária
da primeira dama de Jugoslávia, único carro do meu vizinho
da frente, a relva do meu quintal, Mercedes-benz – 57 98 GP,
música “meu amor” do cantor Firiston, céu.
4. O estado de um objeto é representado pelos seus dados.
5. O estado de um objeto é modificado pelas rotinas sobre tal
objeto (as habilidades);

Exercícios para avaliação


Nos números seguintes, escolha a alternativa mais correta:
1. Os termos “Classe de objetos” e “Instância de Classe” referem-
se a mesma coisa.
a) Sim, “Classe de objetos” e “Instância de Classe” são dois
termos para referir o elemento básico na técnica de
programação orientada a objetos;
b) Não, Instância de classe agrupa as características e
habilidades comuns a todos os objetos de uma
determinada classe.
c) Não, a classe é um descritor, ela descreve todo o
conjunto de objetos da classe ao passo que “Instância de
classe” é uma ocorrência específica de uma classe;
2. Qual é a essência da orientação a objetos?
d) Polimorfismo e abstração;
e) Agrupamento de dados e encapsulamento;
f) Herança e reutilização;
13
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

3. Qual dos seguintes paradigmas usarias para compor uma


solução em java?
a) Agrupamento de código segundo o relacionamento
entre funcionalidades;
b) Agrupamento de código segundo o relacionamento
entre os dados;
c) Agrupamento de código segundo a disposição mais
organizada.
4. Como defines programação orientada a objetos?
a) É aquela vocacionada a processar dados de objetos do
mundo real;
b) É aquela que aproxima a modelação de dados e o
processamento destes ao comportamento dos objetos
do mundo real;
c) É aquela que usa redes neurais para explorar as
potencialidades do cérebro;
5. Qual dos seguintes representa uma classe de objetos
a) Animal
b) O único copo que eu quebrei ontem
c) Carro com chapa ATO 891 MC
6. Qual dos seguintes representa uma instância de classe?
a) Animal
b) Acidente de viação
c) Minha câmera fotográfica Sony com serial
17569812601/91
7. Em programação orientada a objetos “quem” manipula os
dados?
a) A classe de objetos;
b) O objeto;
c) O programador.
8. Qual das seguintes representa vantagem da programação
orientada a objetos?
a) Segurança e consistência de dados;
b) Beleza e organização do código;
c) Nenhuma resposta é correta.

14
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

9. Qual das seguintes representa vantagem da programação


orientada a objetos?
a) Beleza e organização do código;
b) Facilidade de manutenção de código;
c) As duas respostas anteriores estão corretas.
10. Quantas instâncias pode ter uma classe de objetos?
a) Zero, uma ou mais;
b) Nenhuma;
c) Uma e exatamente uma.
Respostas: 1c, 2b, 3b, 4b, 5a, 6c, 7b, 8a, 9b, 10a

Unidade temática 1.2: Processo de desenvolvimento de


aplicações com orientação a objetos

Introdução

Quando se programa baseado no conceito de programação orientada a


objetos (POO) deve-se obedecer a um conjunto de princípios. Conforme
referido na unidade temática anterior, a programação orientada a
objetos assenta em dois conceitos fundamentais, a classe e o objeto.
Nesta unidade será explicado de forma breve o processo de
desenvolvimento com orientação a objetos.
Ao completar esta unidade, você deverá ser capaz de:

• Listar: e explicar todos os passos envolvidos no processo de


programação orientada a objetos;

Objectivos
específicos

Passos para programar orientado a objetos


A programação orientada a objetos começa com a identificação das
entidades que farão parte da aplicação; uma entidade é tudo aquilo
sobre o qual se pretende captar, armazenar, processar e difundir dados.
Para cada entidade deve-se identificar quais os dados se pretende
agrupar, estes dados e as respetivas operações que os manipulam
ficarão descritos na classe (descritor); portanto, o segundo passo após
a identificação das entidades é a criação das classes de objetos que
serão tratados no sistema.

15
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Após a criação das classes de objeto, o passo seguinte é a composição


da solução o que passa pela criação e manipulação dos objetos das
classes [inicialmente criadas]. A manipulação de objetos equivale ao
processamento de dados e é feito recorrendo às “habilidades” do
objeto, que são rotinas que manipulam os dados estas rotinas ficam
representadas em forma de métodos nas classes de objetos.
Para melhor compreensão dos passos anunciados anteriormente
vamos considerar o exemplo seguinte:

Suponha que que se pretenda criar uma aplicação que auxilie no cálculo
da área de um retângulo. Detalhe os passos necessários para criar a
aplicação em causa recorrendo a técnica de programação orientada a
objetos.

Para este problema, seguindo os passos para programar orientado a


objetos, procedemos da seguinte maneira:
1. Identificar as entidades envolvidas: neste caso, tratando-se
do calculo da área de um retângulo, a entidade associada
seria o Retângulo. Para o cálculo da área do retângulo
interessa saber o comprimento e a largura; portanto, estes
seriam os dados a agrupar. A operação sobre estes dados
seria o cálculo da área que é o produto entre a comprimento
e a largura.
2. Criar o descritor: trata-se da criação da classe de objetos
com seus elementos;
3. Criar a aplicação: que no caso iria criar um objeto de tipo
Retângulo e de seguida calcular a área usando a operação
disponibilizada para tal através deste objeto.

Sumário
Nesta unidade temática 1.2 foi apresentado de forma breve o processo
de criação de aplicações usando a técnica de programação a objetos.
São passos aparentemente simples, mas quando bem compreendidos
fornecem um instrumento forte para os programadores iniciantes.

Exercícios de autoavaliação
Perguntas
1. No processo de modelação de dados, o que é uma entidade?
2. Liste os passos a seguir no processo de programação
orientada a objetos;
3. Considere que se pretende criar uma aplicação que permite
calcular que idade determinado individuo tinha num
determinado ano. Detalhe os passos
16
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

necessários para criar a aplicação em causa recorrendo a


técnica de programação orientada a objetos.
4. Em orientação a objetos “quem” manipula os dados?
5. Em uma aplicação para a geração de uma pauta de uma
turma para uma determinada disciplina, qual seria a
entidade principal e quais seriam os seus atributos?

Respostas:
1. Uma entidade é tudo aquilo sobre o qual se pretende captar,
armazenar, processar e difundir dados
2. (a) identificar as entidades e seus dados (b) criar as
respetivas classes de objeto (c) criar objetos e processar seus
dados usando suas rotinas.
3. Detalhe dos passos:
(a) Identificar as entidades envolvidas: neste caso, tratando-
se do calculo da idade de um individuo, a entidade
associada seria o Individuo. Para o cálculo da idade do
individuo interessa saber o ano em que o mesmo nasceu;
seria também necessário saber qual é o nome de tal
individuo; portanto, estes seriam os dados a agrupar2. A
operação sobre estes dados seria o cálculo da área que é
o produto entre a comprimento e a largura.
(b) Criar o descritor: trata-se da criação da classe de objetos
com seus elementos;
(c) Criar a aplicação: que no caso iria criar um objeto de tipo
individuo e de seguida calcular a idade usando a
operação disponibilizada para tal através deste objeto.
4. Em orientação a objetos os dados são manipulados pelo
próprio objeto;
5. A entidade principal seria “Estudante”, os seus atributos
seriam: nome, e as notas obtidas nas avaliações.

Exercícios para avaliação


Das sentenças que seguem assinale com V as verdadeiras e F as falsas:
1. Os passos para a conceção de soluções em POO são: criação
do descritor, criação de objetos e processamento de dados
dos objetos através de suas rotinas;
2. Os passos para a conceção de soluções em POO são:
identificação de entidades envolvidas e seus dados, criação

2
Note que para calcular a idade do individuo num determinado ano, precisaríamos
também de tal ano. Mas este não é um dado do individuo, trata-se de uma variável
externa que somente é necessária no momento do cálculo da idade.

17
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

das respetivas classes de objetos, instanciação de objetos e


invocação das suas rotinas para processamento de dados;
3. Os passos para a conceção de soluções em POO são:
modelar, esboçar, instanciar e manipular.
4. Em POO uma entidade é representada por meio de classe de
objeto;
5. Em um sistema bancário alguns atributos da entidade
principal seriam levantar, depositar, transferir, gerar
estrato;
6. Em um sistema bancário algumas entidades fundamentais
seriam levantar, depositar, transferir, gerar estrato.
7. Em um sistema de gestão académica os seguintes poderiam
ser atributos de algumas entidades, nome estudante, nota
obtida no teste 1 .. n, disciplina, etc.;
8. A entidade principal em um sistema de registo civil é o
Cidadão (ou indivíduo);
9. Em POA lógica de manipulação de dados é programada em
uma classe de objeto dentro de uma rotina chamada
método;
10. Em POA uma “habilidade” corresponde a uma rotina que
manipula os dados.

Respostas: 1-F, 2-V, 3-V, 4-V, 5-F, 6-F, 7-V, 8-V, 9-V, 10-V.

Unidade temática 1.3: Elementos de uma classe de


objetos

Introdução

Na unidade temática anterior foram apresentados os passos para a


conceção de soluções recorrendo a técnica de programação orientada
a objetos. Nesta unidade temática 1.3 vamos apresentar em detalhe os
elementos que compõe uma classe de objeto. Estes elementos serão
apresentados recorrendo a entidade Retângulo discutida no exemplo
da unidade temática 1.2.
Ao completar esta unidade, você deverá ser capaz de:

▪ Listar: e descrever os elementos básicos de uma classe de objetos;


▪ Diferenciar: atributos de instância e atributos de classe bem como
métodos de instância e métodos de classe;

18
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Elementos da classe de objetos


Considere o problema apresentado na unidade temática 1.2; nele o
propósito era calcular a área do retângulo. No primeiro passo
identificamos os dados e as operações necessários para o cálculo da
área. Em uma classe de objetos, os dados são representados por
variáveis de instância ou atributos; as operações são representadas por
métodos. Vamos então esboçar a classe Retângulo com as caraterísticas
mencionadas. A figura seguinte ilustra a classe Retângulo e seus
elementos.

Figura 3: A classe e seus elementos


Na figura 5 podem ser observados os 3 elementos fundamentais de uma
classe de objetos, a saber: Atributos; Construtor e Métodos. No ponto
em destaque no retângulo 1 temos os atributos ou variáveis de
instância; no ponto 2 temos uma variável de classe; o construtor está
em destaque no ponto 3 e no ponto 4 e 5 temos os métodos da classe.
Os métodos definidos no ponto 4 representam as habilidades dos
objetos da classe enquanto que o método definido no 5 é um método
da classe. A seguir são apresentados em detalhe os elementos
apresentados na figura anterior.

19
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Atributos
Conforme referido antes, os atributos descrevem as características de
todos os objetos representados pela classe de objetos. No caso da
classe Retângulo, os seus objetos são descritos por “comprimento” e
“largura”, isso significa que qualquer que seja o retângulo é descrito por
“comprimento” e “largura”; ou por outras: “todo e qualquer retângulo
tem comprimento e largura”. O atributo é definido por um par “tipo de
dados, identificador”. A este par pode se juntar o modificador de
visibilidade. No caso dos atributos do Retângulo, aplicou-se o
modificador “public” para o comprimento e “private” para a largura.
Um modificador de visibilidade define as regras de acesso ao atributo,
o modificador “public” permite acesso ao atributo quer dentro da classe
onde foi definido quer fora da mesma. Já o modificador “private”
permite acesso apenas a partir do interior da classe onde o atributo foi
definido. Para alem destes dois modificadores, existe também o
modificador “protected” que será tratado mais adiante.
Note o atributo “objetosCriados”! Este é ligeiramente diferente dos
outros dois devido a presença da palavra reservada “static”. Trata-se de
um atributo de classe em oposição de atributo de instância. Isso
significa que este atributo não faz parte das caraterísticas do Retângulo
e as instâncias do Retângulo não possuirão esta caraterística. Ao passo
que as variáveis de instância só existem em uma instância, as variáveis
da classe existem sem instância.
O construtor
O construtor é um método especial cuja função é a geração de objetos
(instâncias) da classe. O construtor diferencia-se dos restantes métodos
da classe (1) por usar o mesmo identificador que o da classe e (2) por
não apresentar o tipo de retorno na sua estrutura.
Todo e qualquer objeto (instância) é criado recorrendo a um construtor,
este pode ter sido definido explicitamente pelo criador da classe ou ser
implícito no caso de o criador da classe não incluir nenhum construtor,
neste último caso há possibilidade de se usar o construtor implícito, este
é um construtor que não recebe parâmetros.
Note que dentro da mesma classe de objetos pode se incluir vários
construtores desde que tenham parâmetros diferentes, quer em
quantidade quer em tipos de dados.
No exemplo do retângulo foi definido apenas um construtor o qual está
delimitado pelo número três na figura anterior.
Os métodos
Os métodos representam as habilidades dos objetos, isto é, aquilo que
os objetos são capazes de fazer. Normalmente, eles manipulam os
dados do objeto (valores dos atributos)
20
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

modificando-os ou processando-os ou ainda difundindo-nos. No caso da


classe Retângulo, foram definidos dois métodos, representando as
habilidades dos objetos do tipo Retângulo, são eles: calcularArea e
visualizar. Estes métodos nos dizem respetivamente que (1) “qualquer
que seja o retângulo é capaz de calcular a sua própria área” e (2)
“qualquer que seja o retângulo é capaz de visualizar os seus próprios
dados”. Note a presença do método “imprimirQtdObjetosCriados”, este
método à semelhança da variável “objectosCriados” é um método de
classe e não de instância, portanto não representa nenhuma habilidade
dos objetos do tipo Retângulo. Para a sua invocação não há necessidade
de existência de instância de classe. Quanto aos métodos de instância,
os mesmos só podem ser invocados sobre uma instância ou a partir de
um ponto no interior da classe.
À semelha dos atributos, os métodos possuem um modificador de
visibilidade que define as regras de acesso aos mesmos.
O uso da palavra reservada “this” em classes de objetos
A palavra reservada “this” é usada para fazer referência aos elementos
intrínseco da classe, nomeadamente, variáveis e métodos de instância.
No exemplo da classe Retângulo esta palavra reservada é usada nas
linhas 9 e 10 para fazer referência às variáveis de instância da classe e
na linha 24 para fazer referência ao método “calcularArea” o qual
representa uma habilidade da classe. O uso desta palavra reservada é
proibido para atributos e métodos que não sejam de instância, isto é,
métodos e atributos de classe.
Pacotes e Importação
Quando se projeta uma aplicação é importante definir como as classes
do projeto estarão organizadas. Em java, as classes do projeto são
organizadas em pacotes (package). Um pacote é nada mais nada menos
que um diretório que permite agrupar um conjunto de classes
relacionadas. A definição do pacote a que uma classe pertence é feita
com recurso à palavra reservada “package” seguida pelo identificador
do pacote e aparece logo no início do código. A estrutura de diretórios
de um pacote é separada por ponto. O exemplo seguinte ilustra a
definição de um pacote contendo uma estrutura hierárquica de três
diretórios.

21
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 4: Definição do Pacote

A classe definida na figura anterior ficará armazenada no diretório


“pooa/unidades/unidade_01” do projeto corrente.
Quando em um programa fazemos referência a classes que foram
definidas num pacote diferente do pacote corrente, é necessário fazer
a importação de tais classes. A importação é feita recorrendo à palavra
reservada “import” seguido pelo nome da classe incluindo o pacote em
que tal classe está armazenada. A figura seguinte ilustra a importação
da classe Date do JAVA definida no pacote “java.util”;

Figura 5: Importação

Sumário
Nesta unidade temática 1.3 foram apresentados os elementos
fundamentais de uma classe de objetos, a saber, atributos, construtor e
métodos. Dentro de uma classe podem ser incluídos dois tipos de
atributos, os atributos de instância e os atributos de classe; o primeiro
representa as características dos objetos, o segundo trata-se de
variáveis auxiliares que podem ser usadas a partir da classe. Foi

22
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

explicado que o construtor é um método especial que serve para


construir as instâncias da classe. Finalmente os métodos representam
as habilidades dos objetos eles modificam o estado das variáveis de
instância ou processa-as, estes são os métodos de instancia. Os
métodos de classe são métodos auxiliares que podem ser incluídos na
classe sem representarem habilidade dos objetos da classe.

Exercícios de autoavaliação
Perguntas
1. Liste os elementos principais de uma classe de objetos;
2. Diferencie as variáveis de instância das variáveis de classe;
3. Diferencie os métodos de instância e os métodos de classe;
4. Qual é o propósito do construtor da classe?
5. Para que servem os modificadores de visibilidades?
6. Considere a entidade individuo mencionada no exercício 3
da unidade 1.2. Crie a classe para representar esta entidade
incluindo todos os elementos fundamentais da mesma.
Inclua também uma variável de classe para guardar a
quantidade de instâncias criadas e um método para imprimir
o valor desta entidade.
Respostas:
1. Atributos, construtores e métodos.
2. As variáveis de instância representam as características dos
objetos, elas são intrínsecas ao objeto, elas não existem sem
objeto! As variáveis de classe são variáveis próprias da
classe, elas existem sem instância;
3. Os métodos de instância representam habilidades dos
objetos ao passo que os métodos de classe são métodos
auxiliares e existem sem instância;
4. O construtor serve para criar instâncias da classe de objetos;
5. Os modificadores de visibilidade permitem definir as regras
de acesso aos elementos da classe;
6. Resposta

23
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 6: A classe Individuo

Exercícios para avaliação


Das sentenças que seguem assinale com V as verdadeiras e F as falsas:
1. Em toda e qualquer classe de objetos deve se incluir um
construtor;
2. As variáveis de instância só existem em instância de classe
(objetos);
3. É proibido incluir mais de um construtor numa classe de
objetos;
4. A palavra reservada “this” pode ser usada para referenciar
qualquer elemento de uma classe;
5. O modificador de visibilidade “private” proíbe o acesso ao
elemento da classe fora da classe onde o mesmo foi
definido;
6. O modificador de visibilidade “public” proíbe o acesso ao
elemento da classe fora da classe onde o mesmo foi
definido;
7. Um método de instância só pode ser invocado sobre uma
instância;
Nos números seguintes, escolha a alternativa mais correta:

24
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

8. Ao criar uma classe de objetos, o programador deve sempre


ter em conta:
a) Que a classe deve ter pelo menos um construtor pois
sem construtor não seria possível usá-la;
b) Que todos os atributos devem ser definidos como
“private” para evitar problemas de inconsistência de
dados.
c) Que ao definir um atributo como “private” este não será
acessível para as classes externas a não ser que defina
métodos modificadores de acesso (get’s e set’s).
9. Ao criar uma classe de objetos, o programador deve ter
sempre em conta o seguinte:
a) Que deve incluir na classe um construtor, pois sem
construtor não será possível instanciar tal classe.
b) Ao definir um atributo como “private” o mesmo só pode
ser acedido/modificado (externamente) por meio de
métodos modificadores de acesso (getters e setters)
c) Deve incluir os métodos “equals” e “toString” pois os
mesmos são de carater obrigatório;
10. Ao criar uma classe de objectos, o programador deve ter
sempre em conta:
a) Que todos os atributos definidos como “private” devem
ter os correspontes get’s e set’s;
b) Que os atributos definidos como “public” podem ser
acedidos e manipulados em classes externas e isso
poderá resultar em inconsistência de dados;
c) Que é obrigatório incluir os métodos especiais tal como
“equals” e “toString”;
Respostas: 1-F, 2-V, 3-F, 4-F, 5-V, 6-F, 7-V, 8-c, 9-b, 10-b

Unidade temática 1.4: Instanciação e manipulação de


objetos

Introdução

A instanciação é o mecanismo pelo qual são criados os objetos de uma


determinada classe. A instanciação vem antes da manipulação dos
dados do objeto. Nesta unidade temática vamos discutir estes dois
mecanismos.

25
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Ao completar esta unidade temática 1.4, você deverá ser capaz de:

▪ Compreender: o processo de instanciação e invocação de


métodos sobre instância de classe.
▪ Ser capaz: de instanciar classes e invocar métodos sobre
Objectivos instancias;
específicos ▪ Diferenciar: o uso de métodos e atributos de classe dos métodos
e atributos de instância;
▪ Diferenciar: instância e referência a instância.

Instanciação e Manipulação de instância


Instanciação é o mecanismo pelo qual são geradas instâncias de classe,
isto é, os objetos da classe. Conforme referido na unidade temática 1.1,
um objeto agrega dados e esses dados podem ser manipulados a partir
do próprio objeto recorrendo às habilidades deste.
As instâncias são criadas recorrendo a um dos construtores da classe.
O princípio da programação orientada a objetos é o agrupamento de
dados e manipulação dos mesmos a partir de pontos isolados em
relação ao resto do código, isto é, dentro do próprio objeto.
Voltemos ao enunciado do exemplo 1 apresentado na unidade temática
1. O objetivo é calcular a área de retângulo. Para tal é necessário aplicar
a fórmula de cálculo da área sobre o “comprimento” e a “largura” do
retângulo, estes são os dados do cálculo, portanto precisam estar
agrupados e a classe Retângulo tem esse propósito: criar estruturas de
dados que agrupem o “comprimento” e a “largura” do retângulo.
Usando a habilidade “calcularArea” será depois possível calcular a área
em causa.
A figura abaixo ilustra o programa completo para o cálculo da área de
um retângulo de dimensões 6X3.

26
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 7: Instanciação e Acesso aos elementos de Instancia e da classe

Na figura 4, estão destacadas 5 instruções de código (1) os elementos


da criação da instância do Retângulo (2 e 3) a invocação de habilidades
do retângulo, respetivamente “calcularArea” e “visualizar” e (4 e 5)
acesso ao atributo e método de classe.
Normalmente uma instância de classe fica associada a uma variável,
esta variável é chamada “referência ao objeto”; no nosso exemplo a
referência ao objeto é a variável “r”. Qualquer operação que quisermos
fazer sobre o nosso objeto será invocada sobre a referência. Atenção
que, referência não é o mesmo que objeto! Um objeto tem existência
física na memória e o mesmo objeto pode ter várias referências. A
referência é apenas um meio para nos referirmos ao objeto. O mesmo
objeto pode ter várias referências!
A invocação dos métodos do objeto é feita sobre a referência. No nosso
exemplo, o método “calcularArea” tem retorno, daí que a sua invocação
é feita numa instrução de atribuição com o seu retorno a ser guardado
na variável “área”.
Note a diferença entre métodos de instância e métodos e atributos de
classe. Nos pontos 4 e 5 invocamos elementos de classe! Note que eles
são invocados diretamente sobre a classe e não sobre a instância. O
mesmo não se verifica na invocação dos métodos e variáveis de
instância.

Sumário
Nesta unidade temática 1.4 discutimos os mecanismos de instanciação
e acesso aos elementos da instância. Ficou claro que toda e qualquer

27
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

instância é criada recorrendo ao construtor da classe. Ficou igualmente


claro que o acesso aos elementos de instância (atributos e métodos) é
feito sobre a referência ao objeto. Já os métodos e atributos de classe
são acedidos diretamente sobre o nome da classe sem necessidade de
instanciar a classe.

Exercícios de autoavaliação
Perguntas
1. Como são criadas as instâncias de classe?
2. Diferencie “instância de classe” e “referência a instância”;
3. Qual é a diferença fundamental entre a invocação de
métodos/atributos de instância e métodos/atributos de
classe?
4. Como se deve proceder caso haja interesse no retorno da
invocação de um método sobre um objeto?
5. Considere a classe individuo criada no exercício 6 da unidade
1.3. Com base nesta classe, crie um programa que permite
calcular e visualizar a idade de um individuo nascido a 01 de
março de 1998. No mesmo programa, visualize a quantidade
de indivíduos criados.
Respostas:
1. As instâncias de classe são criadas recorrendo a um dos
construtores da classe. Normalmente uma instância é
associada a uma variável de referência.
2. Uma referência a instância é apenas uma variável que
“aponta” para a instância, ela não tem existência na
memoria, ao passo que a instância existe na memoria e
ocupa espaço;
3. Os métodos e atributos de instância só podem ser invocados
sobre uma instância de classe ao passo que os métodos e
atributos de classe são invocados sobre o nome da classe;
4. Sempre que houver interesse no retorno de um método
invocado sobre um objeto deve se armazenar esse retorno a
uma variável ou invocar o método em um contexto de
expressão.
5. Resolução

28
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 8: Aplicação com orientação a objetos

Exercícios para avaliação


Das sentenças que seguem assinale com V as verdadeiras e F as falsas:
1. Toda e qualquer instância é criada recorrendo ao construtor
implícito da classe;
2. Os métodos e atributos de classe podem ser invocados sobre
a instância da classe;
3. Os métodos e atributos de instância podem ser invocados
diretamente a partir da classe tal como os atributos e
métodos de classe;
4. Toda e qualquer instância é referenciada por meio de uma
variável de referência;
5. Um objeto só pode ter uma e única referência;
6. Uma variável de referência pode apontar a uma ou várias
instâncias;
Nos números seguintes, escolha a alternativa mais correta:
1. Qual é a diferença entre referência a objeto e objeto?
a) O objeto pode existir sem a referência, no entanto a
referência não faz sentido sem objeto;
b) A referência ao objeto é mais importante que o objeto
pois é através dele que invocamos as operações sobre o
objeto;
c) Não existe nenhuma diferença relevante entre estes dois
conceitos.
2. Na instrução mais abaixo:

29
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

a) “A” é uma classe de objetos e “a” é um objeto;


b) “A()” é um método e “a” uma variável;
c) “a” é uma referência a um objeto e “new A()” é um
método construtor;

3. Na instrução apresentada mais abaixo:


a) “o” é uma instância da classe “Object”;
b) “Object ()” é uma classe de objetos e “Object” um tipo
de dados;
c) “o” é uma referência a um objeto do tipo “Object”;

4. Na instrução mais abaixo:


a) “B” é uma classe de objetos e “B (12345)” é um
construtor com 5 parâmetros;
b) “B (12345)” é um método e “b” uma referência a um
objeto;
c) “b” é uma referência a um objeto e “new B(12345)” é
uma chamada ao método construtor;

Respostas: 1-F, 2-V, 3-V,4-F, 5-F, 6-F 7-a, 8-b, 9-c, 10-c.

Exercícios do tema

Exercícios de autoavaliação
Perguntas
1. Qual é a essência de programação orientada a objetos?
2. Descreva os passos aplicados quando se programa orientado
a objetos;
3. Apresente e descreva os elementos de uma classe de
objetos;

30
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

4. Fale sobre a diferença entre elementos de instância e


elementos de classe em uma classe de objetos.
5. Qual é a importância dos modificadores de visibilidade?
6. Recorrendo à técnica de programação orientada a objetos,
crie uma aplicação que permite efetuar as operações
bancárias sobre uma conta, nomeadamente: depósito,
levantamento, e visualização do saldo. Suponha que os
dados da referida conta sejam os seguintes: número da
conta=12345678, saldo inicial: 0 MZN, valor a depositar
10250 MZN, valor a levantar 6000 MZN.
7. Recorrendo à orientação a objetos, crie uma solução que
permite captar, armazenar e fazer segmento das operações
sobre a informação de stock de um armazém. É sabido que
num armazém são armazenados e transacionados
diferentes produtos. Suponha que cada produto seja
descrito por código, preço de compra, preço de venda, stock
disponível e stock total vendido. As operações sobre os
produtos são as seguintes: (1) entrada de stock (2) vendas
ou saída de stock.

A solução concebida deverá usar como exemplo ilustrativo a


criação de um produto qualquer que inicialmente terá um
stock zero, que depois irá verificar uma entrada de 999
unidades e venda de 250 unidades. o programa deverá
visualizar o estado final do produto em causa.
Respostas

1. Agrupamento de dados e manipulação destes de forma


controlada;
2. Identificação das entidades envolvidas; criação do descritor;
criação da aplicação.
3. Os elementos de uma classe de objetos são:
a) Atributos: os atributos podem ser de classe ou de
instância. Os de instância representam as caraterísticas
b) Construtor: método especial que serve para instanciar a
classe;
c) Métodos: definem as rotinas; podem ser de classe ou de
instância. Os métodos de instância modificam o estado
do objeto ou difundem os seus dados. Eles representam
habilidade ou comportamento dos objetos da classe.
4. Os elementos de instância de uma classe são elementos
intrínsecos a ela. Os atributos representam as caraterísticas
de todos os objetos da classe; os métodos representam as
31
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

habilidades/comportamento. Os

32
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

atributos e métodos de instância existem só podem ser


invocados sobre uma instância da classe.
5. Os modificadores de visibilidade definem as regras de acesso
aos elementos da classe. Isso é de grande importância pois
o programador tem a liberdade de dar acesso ou restringir
acesso a determinados elementos da classe e desta forma
garantir acesso seguro a estes.
6. Resolução

Figura 9: A classe Conta; representa o descritor da Conta

33
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 10: Aplicação com operações bancárias

7. Resolução

34
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 11: A classe Stock

Figura 12: Operações sobre Stock

35
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Exercícios para avaliação


Nos números seguintes escolha a opção mais correta.
1. Qual destas afirmações é correta?
a) Toda classe de objeto tem um construtor implícito; trata-
se de um construtor sem parâmetros;
b) O uso de pacotes é obrigatório em um projeto java
c) Numa classe de objetos pode se incluir zero, um ou mais
construtores
2. Em uma classe de objetos a palavra “this” serve para:
a) Fazer referência a elementos definidos dentro da classe;
b) Fazer referência a elementos estáticos definidos na
classe ou na superclasse;
c) Fazer referência a elementos de instância definidos na
classe ou na superclasse;
3. Em um retângulo:
a) Comprimento e largura representam as caraterísticas de
todo e qualquer retângulo;
b) Comprimento e largura representam as habilidades de
todo e qualquer retângulo;
c) O comprimento e largura representam as caraterísticas
ou habilidades de todo e qualquer retângulo.
4. Os elementos de uma classe de objetos são:
a) Construtores, Métodos de Instância e Variáveis de
instância
b) Construtor, Métodos de Instância e de Classe e Atributos
de instância e de classe;
c) Todos os elementos da classe e das suas superclasses.
5. Dentro de um método estático é proibido:
a) Fazer referência aos atributos de instância;
b) Fazer referência aos atributos de classe;
c) As duas opções estão corretas.
6. Ao criar uma instância sobre a qual pretendemos efetuar
operações, o que devemos fazer?
a) Associar essa instância a uma variável;
b) Criar uma referência para esse objeto;

36
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

c) As duas opções estão corretas.


7. Em uma classe de objetos:
a) As variáveis/atributos representam as habilidades dos
objetos;
b) Os métodos e variáveis representam as habilidades dos
objetos;
c) Os métodos de instância representam as habilidades ou
comportamento dos objetos.
8. Em uma classe de objetos o que não pode faltar na definição
de um atributo?
a) O modificador de visibilidade, tipo de dados e o
identificador;
b) O tipo de dados e o identificador;
c) O modificador de visibilidade, o tipo, identificador e a
indicação de que o atributo é de classe ou de instância.
9. Em uma classe de objetos para que serve a palavra reservada
“this”?
a) Para diferenciar elementos de instância dos elementos
de classe;
b) Para diferenciar elementos de instância [definidos na
classe ou acessíveis a partir da classe] do resto dos
elementos;
c) Serve para fazer referência a qualquer elemento
definido no interior da classe.
10. Qual destas expressões é falsa?
a) Um objeto pertence a uma e única classe;
b) Em POO o objeto tem representação na memória do
computador em tempo de execução;
c) Em POO o estado do objeto é representado pelos seus
dados;

Respostas: 1-c, 2-c, 3-c, 4-b, 5-a, 6-c, 7-c, 8-b, 9-b, 10-a.

Referências Bibliográficas

Caelum. Java e Orientação a Objetos. Consultado em abril de 2021. Disponível em


https://www.caelum.com.br/apostila-java-orientacao-objetos

37
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Oracle. Object-Oriented Programming Concepts; Consultado em abril de 2021.


Disponível em
https://docs.oracle.com/javase/tutorial/java/concepts/index.html

38
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

TEMA – II: OS PILARES DA PROGRAMAÇÃO ORIENTADA A OBJETOS. ENCAPSULAMENTO,


POLIMORFISMO E ABRASTRAÇÃO.

Unidade temática 2.1: Encapsulamento


Unidade temática 2.2: Herança
Unidade temática 2.3: Polimorfismo e Abstração
Unidade temática 2.4: Exercícios do tema

Unidade temática 2.1: Encapsulamento

Introdução

A orientação a objetos visa fundamentalmente a criação de aplicações


fidedignas e de baixo custo de manutenção. A manutenção é o processo
pelo qual as aplicações são melhoradas, quer em termos de
performance, quer em termos de inclusão de novas funcionalidades.
Além disso, a manutenção tem em vista a correção de bugs que forem
detetados durante o funcionamento da aplicação. Essa tarefa [de
manutenção] fica facilitada se o código for legível e se os conceitos
fundamentais de orientação a objetos tiverem sido bem
implementados. O encapsulamento é um dos princípios da
programação orientada a objetos que ajuda no alcance das
características desejáveis em aplicações que se pretende que sejam
fidedignas e de baixo custo de manutenção. Nesta unidade temática 2.1
serão considerados os conceitos em volta do princípio de
encapsulamento.
Ao completar esta unidade, você deverá ser capaz de:

▪ Compreender: o conceito de encapsulamento e como resolve


problemas relacionados com segurança e consistência de dados;
▪ Explicar: como o encapsulamento pode ser conseguido em java;
Objectivos
▪ Conceber: classes de objetos que obedeçam ao principio de
específicos encapsulamento;

Definição
Encapsulamento é o mecanismo pelo qual um objeto isola os seus
dados bem como a lógica do processamento dos mesmos em relação às
classes que o manipulam. O encapsulamento visa garantir que os dados
do objeto serão manipulados de forma segura evitando situações de
inconsistência de dados que poderiam advir do manejamento incorreto

39
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

dos mesmos. Além disso, o encapsulamento “oculta” a complexidade


das operações sobre os dados do objeto limitando-se a fornecer uma
interface de comunicação para a manipulação dos dados do objeto.

Encapsulamento na resolução de problemas de inconsistência


Para melhor entender o conceito de encapsulamento considere a
solução apresentada a seguir. Trata-se de uma solução para o manejo
dos dados de um sistema de gestão de Stock. Nesta solução existe um
descritor (a classe Stock) e a aplicação responsável pela criação e
manipulação do stock [a classe App01].
O descritor descreve os elementos de todo e qualquer produto em stock
no âmbito desta solução. Esta classe possui quatro atributos,
nomeadamente: (1) produto – O nome do produto; (2) stockDisponivel
– a quantidade de itens do produto disponíveis; (3) totalVendido – a
quantidade total de unidades vendidas e (4) totalAdquirido –
quantidade total de itens adquiridos. A classe Stock define ainda
“habilidades” dos objetos do tipo “Stock”; estas habilidades são
representadas pelos métodos seguintes: (1) “efectuarAquisicao” –
Efetua uma nova aquisição do produto, acrescendo a quantidade
adquirida [recebida pelo parâmetro] ao stockDisponivel; incrementa
esta quantidade ao total adquirido (2) “efectuarVenda” – Efetua avenda
do produto, retirando a quantidade da venda ao stock do produto e
acrescendo esta quantidade a quantidade total vendida (3) “print” que
imprime o estado atual do stock do produto. Note que para além dos
valores dos atributos, este método imprime também a informação da
consistência do stock. Um produto em stock está num estado
CONSISTENTE se a diferença entre o total vendido e o total adquirido
coincidir com o stock disponível.

40
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 13: O descritor de Stock

41
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 14: Aplicação que manipula o Stock


Note que o programa App01, aplica conceitos de orientação a objetos
para tratar operações sobre o stock. Na primeira parte do código (linhas
6, 7 e 9), o objeto “stock” é manipulado por meio das “habilidades” do
objeto, nomeadamente: “efectuarAquisicao”, para efetuar uma
aquisição de 150 unidades; “efectuarVenda”, para efetuar uma venda
de 50 unidades, e “print” para imprimir os dados do stock. Note que o
estado do stock é “CONSISTENTE” o que significa que a diferença entre
o total de aquisições e o total de vendas coincide com o stock
disponível.
Na segunda parte do código há uma série de instruções que modificam
os valores dos atributos do stock: primeiro (linha 11) modifica-se o stock
disponível para 150, depois (linha 12) modifica-se o total adquirido para
200 e finalmente (linha 13) modifica-se o total vendido para 300. A
seguir imprime-se os dados do stock recorrendo-se ao método “print”
(linha 15). Nota-se claramente que o estado do stock é inconsistente
visto que a diferença entre o “totalAdquirido” e o “totalVendido” não
coincide com o stock atual. Estamos aqui perante um problema típico
de aplicações mal concebidas, o problema de inconsistência de dados.
O que causou a inconsistência mencionada anteriormente? Este
problema surgiu porque os dados do stock foram “mexidos” de forma
incorreta não obedecendo a lógica dos mesmos. Pela lógica, o stock
atual final do produto é igual a diferença entre o total adquirido e o total
vendido, o que não se verifica no código aqui tratado.
A programação orientada a objetos pressupõe que os dados intrínsecos
ao objeto sejam manipulados a nível do objeto e não fora deste pois
quem melhor conhece as regras dos dados é o “próprio” objeto através
daquilo que foi definido no descritor.

42
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Deve ficar claro que uma classe de objetos pode ser usada em vários
momentos, em vários pontos de um projeto e de vários projetos e não
está garantido que todos os que irão usar a classe conheçam as regras
sobre os dados. O encapsulamento garante que quem mexe com os
dados é o próprio objeto e não terceiros.
E como é conseguido o encapsulamento?
Encapsular, passa em primeiro lugar por inibir terceiros de mexer
diretamente com os dados “sensíveis” do objeto; por dados sensíveis,
entenda-se dados que só o próprio objeto conhece as regras para a sua
manipulação. Isso é conseguido tornando privados os atributos
sensíveis da classe de objetos e isso é feito recorrendo ao modificador
de visibilidade “private”, visto que este modificador garante que o
atributo só pode ser acedido a partir de dentro da classe de objeto dono
do atributo.
Vamos modificar a definição dos atributos da classe Stock, tornando-os
“private”.

Figura 15: Classe Stock com atributos sensíveis definidos como “private”

Agora não será mais possível o acesso aos atributos “stockDisponivel”,


“totalVendido” e “totalAdquirido” a partir de classes externas. O
programa App01 deixará de compilar uma vez que ele viola as regras de
acesso aos atributos “private”.

43
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 16: Erros com encapsulamento


Figura 17: Parte de código do programa “App01” que não irá compilar mais devido a
violação das regras de acesso
Agora, nenhuma outra classe terá acesso direto aos atributos da classe
Stock!
Mas então, como serão acedidos os valores destes atributos em caso de
necessidade? Por exemplo, se se pretender saber o stock disponível,
como o mesmo será acedido?
O encapsulamento pressupõe que as regras de acesso e manipulação
dos dados do objeto sejam ditadas pela respetiva classe objeto. É a
classe de objetos que define quais os dados do objeto poderão ser
acedidos e como serão acedidos. A manipulação da lógica dos dados do
objeto fica a cargo do próprio objeto. Quanto ao acesso aos atributos
do objeto, quer para a leitura (acesso aos seus valores) quer para a
edição (alteração dos seus valores), a classe de objetos define métodos
especiais que permitem acesso seguro aos dados, os chamados
“Getters e Setters”
Getters e Setters
Os métodos “getters” e “setters” são métodos especiais que tem como
propósito dar acesso aos atributos do objeto. O acesso pode ser para
leitura (acesso aos valores dos atributos, usando “getters”) ou para
edição (modificação dos valores dos atributos, usando “setters”). O
criador do descritor é o único responsável por selecionar quais os
atributos poderão ser acedidos por terceiros. Isso significa que nem
todos os atributos serão disponibilizados em todas as situações. Por
exemplo, na classe Stock [apresentada
44
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

anteriormente], não faria muito sentido dar acesso de edição ao


atributo “stockDisponivel” pois o valor deste atributo é modificado
pelas operações sobre o stock [aquisições e vendas].
O acesso aos atributos por meio dos “getters” e “setters” reduz a
possibilidade de inconsistência de dados, visto que quer a leitura quer
a edição dos atributos é feita de forma controlada, com a verificação da
validade dos dados. O criador da classe “sabe” melhor o que fazer
quando um determinado atributo é modificado.
Vamos agora escrever os “getters” e os “setters” da nossa classe!

Figura 18: A classe Stock com métodos modificadores de visibilidade

Agora a classe “Stock” tem interface de acesso aos seus atributos, os


getters e os setters. Note que não se criou o “setter” para o
“stockDisponivel”, pois conforme referido antes, não faria nenhum
sentido permitir a modificação desse atributo. Note ainda que os
atributos “totalAdquirido” e “totalVendido” só são modificados se não
provocarem inconsistência de dados; por exemplo: se o novo valor para
o atributo “totalAdquirido” for inferior ao valor no atributo
“totalVendido”, a modificação é rejeitada pois isso iria resultar em stock
negativo.

45
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Como se pode notar, esta abordagem reduz a possibilidade de erros de


inconsistência de dados. Além disso, isola toda a complexidade de
manipulação e validação de dados para o próprio objeto.
A figura seguinte ilustra o programa “App01” modificado e
compatibilizado com o novo descritor de Stock.

Figura 19: Programa “App01” modificado para obedecer aos princípios de


encapsulamento
No código da figura anterior, as partes marcadas com “x” são as partes
que violavam o princípio de encapsulamento; parte deste código foi
substituído com o código logo abaixo [com linhas marcadas com “✓”].

Sumário
Nesta Unidade temática 2.1 estudamos e discutimos o princípio de
encapsulamento e suas vantagens. Este principio visa isolar a
complexidade das operações sobre os dados; está abordagem garante
que os dados são manipulados de forma correta pois a manipulação dos
mesmos é feita por quem melhor os conhece, o criador do descritor! O
encapsulamento garante:

46
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

✓ Fácil interpretação do código, uma vez que toda a complexidade


de processamento fica “escondida” no descritor; quem usa o
objeto não precisa saber os detalhes do seu funcionamento
interno, apenas usa a interface disponibilizada pelo objeto para
manipulá-lo.
✓ Fidedignidade dos dados, pois os dados são “mexidos” de forma
segura a partir do interior do objeto;
✓ Fácil manutenção do código, pois as mudanças dentro do
descritor têm menor impacto sobre as restantes partes da
solução, pois a comunicação com os objetos é feita por meio de
interfaces de comunicação.

Exercícios de autoavaliação
Perguntas
1. Defina em poucas palavras o que é encapsulamento.
2. Qual é o propósito do encapsulamento?
3. Como se consegue o encapsulamento?
4. Quais são as vantagens do encapsulamento?
5. Considere o programa App02 apresentado na figura
seguinte.
a) Diga que efeitos, a instrução no retângulo 1, produz
sobre os atributos do objeto “stock” criado na linha 4 do
programa.
b) A instrução no retângulo 2 não produz nenhum efeito,
justifique porquê.

Figura 20: App02

47
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

6. Crie um programa que permite efetuar uma aquisição e


venda sobre uma stock cujo produto é indicado pelo
utilizador. As quantidades da operação deverão também ser
indicados pelo utilizador. No caso de a quantidade a vender
for superior ao stock disponível, o programa deverá emitir
uma mensagem de erro. Caso contrário deverá visualizar o
estado atual do stock.
7. Modifique a última versão da classe “Stock” apresentada
nesta unidade temática 2.1. Adicione nela o método
“transferir” com a seguinte assinatura: “public boolean
transferir (Stock stockDestino, int quantidade)”. Este
método deverá transferir a quantidade passada pelo
parâmetro do objeto “this” para o stockDestino.
8. Crie uma aplicação que permite efetuar as operações de
aquisição, venda e transferência sobre dois stocks “stock01”
e “stock02”. O programa deverá começar por criar os stocks
em causa com dados lidos pelo teclado. Após a criação dos
stocks, o programa deverá apresentar um menu repetitivo
com as seguintes opções e as respetivas funcionalidades:
a) Efetuar uma aquisição para o stock01: permite efetuar
uma aquisição de uma quantidade lida pelo teclado para
o stock01;
b) Efetuar uma aquisição para o stock02: permite efetuar
uma aquisição de uma quantidade lida pelo teclado para
o stock02;
c) Efetuar venda do stock01: permite efetuar uma venda do
stock01;
d) Efetuar venda do stock02: permite efetuar uma venda do
stock02;
e) Transferir do stock01 para stock02: permite transferir
uma quantidade lida pelo teclado, da stock01 para
stock02.
f) Visualizar stock: permite visualizar os dados dos dois
stocks
g) Sair: termina a execução do programa.
Respostas:
1. Encapsulamento é o mecanismo através do qual um objeto
isola os seus dados (bem como a lógica do processamento
destes) em relação às classes que o manipulam.
2. O encapsulamento evita acesso indevido aos dados de um
objeto garantido que os mesmos são acedidos de forma
segura através de pontos específicos do código;

48
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

3. O encapsulamento é conseguido através do uso do


modificador de visibilidade “private” aos atributos de
instância;
4. As vantagens do encapsulamento são:
a) Fácil interpretação do código;
b) Fidedignidade dos dados;
c) Fácil manutenção do código.
5. Respostas:
a) A instrução em causa modifica os valores dos atributos
“stockDisponivel” e “totalAdquirido” adicionando-lhes
100 unidades.
b) Pois a quantidade a vender é superior que a o stock
disponível;
6. Resposta

Figura 21: Operações sobre Stock

7. Resposta

49
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 22: O método transferir stock

8. Resposta

Figura 23: Aplicação com Stock

50
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

O método menu

Figura 24: Menu da Aplicação com Stock

Exercícios para avaliação


Perguntas
Nos números seguintes marque com V as afirmações verdadeiras e F as
falsas:
1. O encapsulamento é conseguido por meio do uso do
modificador “private”;
2. Quando aplicamos o conceito de encapsulamento não
permitimos que terceiros tenham acesso aos dados do
objeto;
3. O encapsulamento limita-se a ocultar os dados do objeto
para que não sejam mexidos por terceiros;
4. Uma classe de objetos que aplica o conceito de
encapsulamento disponibiliza todos os seus atributos por
meio de getters e setters;
5. Uma das vantagens do encapsulamento é beleza e
organização do código;
Nos números seguintes, escolha a alternativa mais correcta.
6. Como se consegue o encapsulamento?
a) Isolando os objetos, isto é, evitar que eles se
comuniquem com outros;
b) Tornando o “acesso direto” aos atributos, exclusivo ao
objeto;
c) Por meio de “exceptions” garantindo acesso seguro aos
dados.

51
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

7. Qual dos seguintes benefícios se consegue com o


“encapsulamento”?
a) Reutilização, Ajustabilidade e Abstração;
b) Mutabilidade, Polimorfismo e escalabilidade;
c) “Manutenibilidade”, Integridade e Consistência.
8. Uma aplicação que aplica corretamente o conceito
“encapsulamento”
a) Trata todas as “exceptions” que podem ser rebentadas
em partes essenciais da aplicação;
b) Pode facilmente ser “mexida” por qualquer
programador;
c) Suas partes podem ser modificadas sem afetar o resto da
aplicação.
9. Para evitar “desordem” na manipulação de dados que
conceito empregarias?
a) Encapsulamento;
b) Herança;
c) Polimorfismo;
10. É verdade que quando se programa seguindo o
encapsulamento
a) Um objeto não pode manipular os dados de um outro
sem recorrer aos métodos deste;
b) Um objeto não pode manipular os dados de um outro
objeto;
c) Uma classe não pode manipular os dados de uma outra
classe.

Respostas: 1-V, 2-F, 3-F, 4-F, 5-V, 6-b, 7-c, 8-c, 9-a, 10-a

Unidade temática 2.2. Herança

Introdução

A herança é um dos conceitos de programação orientada a objetos que


adiciona poder a técnica de orientação a objetos. Ela figura como uma
das bases para se conseguir polimorfismo, ora este último é um dos
pilares da orientação a objetos. Nesta unidade temática número 2.2

52
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

vamos entrar ao fundo do conceito herança, sua definição, suas


vantagens boas práticas de programar com herança.

Ao completar esta unidade, você deverá ser capaz de:

▪ Definir: com clareza o que é herança;


▪ Enumerar: as vantagens da herança;
▪ Aplicar: corretamente o conceito herança onde for necessário durante
Objectivos o processo de desenvolvimento de aplicações.
específicos

O Problema
Suponha que se pretende desenvolver uma aplicação bancária para
auxiliar nas operações de um determinado banco. Suponha ainda que o
banco em causa fornece dois tipos de contas a saber, Contas a Ordem e
Contas a Prazo. Todas as contas possuem um número, titular e saldo. As
Contas a prazo possuem, para além dos atributos comuns, a data do
inicio da aplicação e a duração da aplicação. As Contas a Ordem
possuem, o regime de titularidade o qual pode ser cada um destes três:
individual, solidária ou conjunta. Toda vez que há um depósito numa
conta a prazo, o saldo é acrescido com um extra de 3% do valor do
depósito.
Usando as bases apresentadas até agora, para resolvermos este
problema criaríamos 2 classes de objetos, a classe ContaOrdem e
ContaPrazo. Em cada uma das classes teríamos 3 atributos, a saber:
número, titular e saldo.
Cada uma das classes teria as suas habilidades que por sinal são muito
parecidas, a saber: levantamento, deposito, transferência e impressão
da informação da conta.
Vamos imaginar que depois de termos o nosso sistema funcional, fosse
necessário acrescentar mais um atributo a cada uma das classes,
digamos, a data de abertura da conta. Seria necessário incluir em cada
uma das classes este novo atributo. E se tivéssemos que incluir o
método para calcular a “idade” da Conta? Com certeza teríamos de
adicionar este método em cada uma das classes.
Vamos imaginar ainda que fosse necessário introduzir uma validação
para o número da conta, por exemplo, vamos supor que o número da
conta deve ter exatamente 5 dígitos e que o último dígito é um dígito
de verificação baseado num algoritmo matemático qualquer. O código
de validação do número teria de ser introduzido em cada uma das duas
classes. E se no futuro quiséssemos corrigir ou melhorar o código de

53
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

validação do número? Também seria necessário efetuar as alterações


nas duas classes!
Esta solução não é ótima, pois, obriga-nos a replicar o esforço toda vez
que quisermos inserir uma modificação comum a todas as classes do
modelo do sistema. Além disso, nesta solução, “espalhamos” código
idêntico o que tornará a manutenção dificultosa. Precisamos de uma
solução melhor para resolver este problema!
E se fosse possível agrupar todos os atributos e habilidades comuns
numa classe e invocar esta classe nas restantes classes do sistema
acrescentando nelas os atributos não comuns?! Essa solução seria ideal
pois todos os atributos e métodos comuns estariam agrupados e o
tratamento destes estaria centralizado! Em java é possível conseguir
esse efeito! E isso consegue-se recorrendo a um mecanismo chamado
Herança que é um dos conceitos fundamentais da orientação a objetos.

Definição
Herança é o mecanismo pelo qual uma classe (subclasse/descendente)
herda as características e habilidades de uma outra classe (superclasse).
Neste tipo de relacionamento, diz-se que a subclasse estende a
superclasse. A subclasse é comumente chamada “classe filha” e a
superclasse “classe mãe”.
O mecanismo de herança, aumenta os ganhos da programação
orientada a objetos, uma vez que permite que as características e
habilidades de determinadas classes de objetos sejam expandidas
(estendidas) sem necessidade de se “remexer” o que já existe. A classe
“filha” poderá acrescentar [a ela mesma] atributos e métodos, que não
foram contemplados na classe “mãe”; além disso, a classe “filha”
poderá reescrever algumas funcionalidades da classe “mãe”, isto é,
implementar novamente funcionalidades definidas na classe “mãe” de
tal maneiras a adequa-las às suas necessidades específicas.
Para estabelecer uma herança entre duas classes, usa-se a palavra
reservada extends.
Vamos resolver o problema levantado anteriormente usando o
mecanismo de herança. Primeiro vamos criar a classe mãe (a classe que
contêm todos os atributos e métodos comuns). Chamemos esta classe
de Conta. Depois iremos criar as classes filhas e nestas vamos
acrescentar os atributos e métodos a elas exclusivos.
A classe Conta [apresentada na figura 25] será a base para as restantes
contas. As classes “ContaOrdem” [figura 26] e “ClassePrazo” [figura 27]
irão estender esta classe.
Note o uso do modificador “protected” para os atributos da classe
“Conta”. Este modificador garante que o atributo (ou método) será
visível nas subclasses da classe onde foi
54
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

definido, mas o mesmo não será visível noutras classes diferentesdestas


que não estejam no mesmo pacote onde a classe foi definida. Nocaso da
classe “Conta” todos os atributos foram definidos como “protected”;
isso significa que, as classes “ContaOrdem” e “ContaPrazo” (ou
qualquer outra classe que estender a classe “Conta”)terão acesso direto
a estes atributos. Atenção que nalguns casos, o programador da
superclasse pode não querer que os atributos sejam acessíveis para as
subclasses, nessas situações os atributos são definidos como “private”.

Figura 25: A classe Conta (A classe "mãe" ou superclasse)

55
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 26: A classe ContaOrdem (sub classe da classe Conta)


A classe “ContaOrdem” estende a classe “Conta”. Note o uso da palavra
“extends” no cabeçalho da definição da classe.
A classe “ContaOrdem” acrescentou o atributo “regime”, então, os
objetos da classe “ContaOrdem” terão mais uma característica para
além das caraterísticas definidas na classe “Conta”.
Note o uso da palavra “super” no construtor da classe “ContaOrdem”.
A palavra “super” é uma palavra reservada usada para fazer menção a
qualquer atributo, método ou construtor definido na superclasse. Neste
caso específico, usa-se o “super” para invocar o construtor da
superclasse “Conta” para a inicialização dos atributos definidos nesta
classe.

56
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 27: A classe "ContaPrazo"

Analogamente, a classe “ContaPrazo” estende a “Conta”. Esta classe


acrescenta dois atributos, a saber, “dataInicio” e “duracao”. Além disso,
a “ContaPrazo” reescreve o método “depositar” visto que tem uma
ligeira diferença com o método “depositar” definido na superclasse
“Conta”.

Sobreposição/Reescrita(Overriding) de métodos
Reescrita ou sobreposição (overriding, em inglês) é o mecanismo pelo
qual uma subclasse reescreve métodos definidos na superclasse para
adequa-los às suas necessidades específicas.
Métodos reescritos devem ter mesma assinatura que os da superclasse,
isto é, o nome, os parâmetros e o retorno deve coincidir.
No caso da classe “ContaPrazo”, a diferença no método “depositar”
consiste no facto de este adicionar 3% extra ao saldo depois do
depósito.
Novamente, note o uso da palavra “super”. Neste caso o “super” é
usado para fazer referência a um método definido na superclasse, o
método “depositar” da classe “Conta”

57
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Manipulação de objetos de classe com Herança


Dissemos que a classe filha (subclasse) herda os métodos [e os
atributos] da classe mãe (superclasse). Isto significa que podemos
invocar estes métodos a partir dos objetos da subclasse como se [estes
métodos] tivessem sido definidos na subclasse.
Exemplo
Elabore um programa que gera dois objetos, um do tipo “ContaOrdem”
e outro do “ContaPrazo”. Após a criação destes objetos efetue uma
operação em cada um deles e de seguida visualize os seus dados.
Resolução

Figura 28: Manipulação de objetos com herança


Note que invocamos, sobre objetos do tipo “ContaOrdem” e
“ContaPrazo”, métodos definidos na classe “Conta”, como se estes
tivessem sido definidos nestas classes (subclasses).

A classe “Object” e reescrita dos seus métodos


A classe “Object” é uma classe disponibilizada pelo java; ela é
considerada a “mãe” [ou raiz] de todas as classes “java” quer as que
fazem parte das livrarias do “java” quer as novas classes criadas pelos
programadores. Existe uma herança implícita entre a classe “Object” e
todas as classes escritas em java. Isso significa, por exemplo, que a
classe “Conta” apesar de não fazer referencia a “extends Object”, por
detrás, ela é filha da classe “Object”, logo, herda os seus atributos e
métodos desta classe.
A classe “Object” define uma série de métodos que permitem
manipular o objeto, dentre os quais, podemos mencionar os seguintes:
“equals” e “toString”. A reescrita dos métodos da classe “Object” é
fundamental conforme veremos na unidade 1.3 que trata de
“Polimorfismo”.

58
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

“O toString”
O “toString” é um método definido na classe “Object” para fornecer a
descrição do Objeto por meio de uma String. Normalmente, essa
descrição é composta pelos valores dos atributos relevantes do objeto.
Este método tem a seguinte assinatura “public String toString ()”.
Vamos rescrever este método nas classes do nosso modelo

Figura 29: o método "toString" na classe Conta

Note que o método “toString” da classe “ContaOrdem” [e da classe


“ContaPrazo” apresentada a seguir, faz referência ao correspondente
método da superclasse “Conta”. Neste caso, à descrição da “Conta”
genérica, é adicionado os valores dos atributos das subclasses.

Figura 30: O método "toString" da classe "ContaOrdem"

59
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 31: O método "toString" na classe ContaPrazo

“O equals”
O “equals” é um método disponibilizado pela classe “Object” para
determinar se dois objetos são iguais ou não. O método “equals” da
classe “Object” retorna “true” se e somente se os dois objetos “forem
o mesmo objeto”, o que na maioria dos casos não é útil para casos
específicos; por essa razão, o método “equals” precisa ser reescrito.
Vamos reescrever o método “equals” na nossa superclasse “Conta”

Figura 32: O método "equals"

Conforme referido antes, o método “equals” determina a igualdade de


dois objetos, o objeto “this” e o objeto passado pelo parâmetro. É o
programador que define as regras de igualdade dos objetos seguindo a
lógica específica para o caso que estiver a tratar.
No caso da “Conta”, consideramos que duas contas são iguais se elas
tiverem o mesmo número de conta.
60
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Note o uso da palavra “instaceof”; esta palavra verifica se um


determinado objeto é ou não instância de uma determinada classe. No
nosso exemplo, verificamos se o objeto “obj” é instância da classe
“Conta” ou não e pela lógica que definimos, se o objeto a comparar não
for do tipo “Conta”, presumimos que ele não pode ser igual ao objeto
“this”.
Note ainda o uso do “casting” na linha 14. Este “casting” é necessário
para extrair as características da Conta no objeto recebido pelo
parâmetro.

Sumário
Nesta unidade temática 2.2 abordamos herança. Com base num
exemplo foi apresentada a necessidade do uso da herança. Ficou claro
que o uso da herança garante reutilização do descritor fornecendo uma
maneira transparente para novos descritores fazerem uso dos
elementos de um descritor “mãe” e evitando dessa forma repetição de
código. A herança é poderosa pois para além de permitir que as
subclasses herdem atributos e métodos da superclasse, permite às
subclasses reescrever os métodos da superclasse para adequa-los à
necessidades específicas.

Exercícios de autoavaliação
Perguntas
1. Defina o conceito herança;
2. Quais são os problemas que a herança se propões a
resolver?
3. O que significa “reescrita” de métodos e em que
circunstâncias fazemos uso dela?
4. Com base no modelo de classes criado nesta unidade
temática 2.2, elabore um programa que permite criar uma
um objeto do tipo ContaOrdem e outro do tipo ContaPrazo
(Os dados das contas devem ser lidos pelo teclado). Depois
da criação das contas efetue o seguinte:
a) Deposite 10,000.00 em cada uma das contas;
b) Visualize o saldo de cada uma das contas;
c) A que se deve a diferença dos saldos finais?
5. Suponha que se pretende desenvolver uma aplicação para
auxiliar na gestão de indivíduos envolvidos no processo de
formação da ISCED. Para esta aplicação, importa recolher e
processar os dados dos diferentes tipos de indivíduos que
participam dos processos acadêmicos, nomeadamente:
estudantes, docentes e coordenadores
61
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

das áreas científicas. Suponha que para cada entidade, os


dados que importa recolher são os seguintes:
• Estudantes: nome, ano nascimento, código de
estudante;
• Docentes: nome, telemóvel, ano nascimento e nível
académico;
• Coordenadores: nome, email, ano nascimento e área
de coordenação

Suponha ainda que será necessário imprimir o nome e a


idade dos indivíduos.
a) Usando os conhecimentos adquiridos crie um modelo de
dados para a aplicação descrita.
b) Inclua no modelo o “toString” e o “equals”.
c) Elabore um programa que ilustra a criação de objetos de
cada um dos tipos mencionados acima; os dados dos
objetos em causa devem ser definidos pelo
programador. Imprima o nome e a idade de cada
individuo criado anteriormente.
d) No modelo de dados criado na alínea a), reescreveste
algum método? Se sim, justifique porquê?
Respostas:

1. Herança é o mecanismo pelo qual uma classe


(subclasse/descendente) herda as características e
habilidades de uma outra classe (superclasse). Neste tipo de
relacionamento, diz-se que a subclasse estende a
superclasse. A subclasse é comumente chamada “classe
filha” e a superclasse “classe mãe”.
2. A herança evita repetição de código e garante fácil
manutenção do código;
3. A reescrita de métodos significa reescrever determinado
método (definido na superclasse) na subclasse de tal
maneiras a adequa-lo às necessidades específicas desta.
4. Resposta (a e b)

62
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 33: Aplicação com contas bancárias


Resposta c: a conta a prazo acresceu 3% ao valor do depósito (no
método “depositar” reescrito)
5. Resolução
(a e b) O modelo em causa é composto por quatro classes,
nomeadamente: a superclasse “Individuo”, as subclasses
“Estudante”, “Docente” e “Coordenador”, as mesmas estão
representadas nas figuras seguintes:

63
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 34: A classe Individuo

Figura 35: A classe Estudante

64
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 36: A classe Docente

Figura 37: A classe Coordenador

6. (c)

Figura 38: Aplicação com individuos

(d) Sim, para cada uma das subclasses houve necessidade de


se reescrever o método toString pois cada uma destas
classes acrescentou atributos.

65
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Exercícios para avaliação


Perguntas
Nos números seguintes, marque com V as afirmações verdadeiras e F as
falsas:
1. A herança garante que uma subclasse herde todos os
atributos e métodos da superclasse.
2. A reescrita permite que as subclasses adicionem métodos
que não foram definidos pela superclasse.
3. Se “A” e “B” são subclasses de uma mesma classe, então elas
partilham os métodos e atributos definidos na superclasse.
4. Se a classe “D” e “E” são subclasses de uma mesma
superclasse então elas têm exatamente mesmos métodos e
mesmos atributos.
5. Se a classe “X” é subclasse da classe “Z” e esta última assina
o método “m()”, então em todas as circunstâncias este
método pode ser invocado sobre as instâncias de “X”.
Nos números seguintes, escolha a alternativa mais correta:

6. A reescrita (overriding) de métodos é um conceito


estritamente ligado à
a) Herança;
b) Encapsulamento;
c) Modularização.
7. Suponha que te está disponível a classe “ElectroMachine”
que disponibiliza vários métodos de automação incluindo o
método “doBasicTask”. Se o funcionamento do método
“doBasicTask” não se adequar perfeitamente às tuas
necessidades o que farás?
a) Ignorar a classe “ElectroMachine” e construir uma classe
similar com o método adequado às tuas necessidades;
b) Aplicando o conceito de herança, reescrever o método
“doBasicTask” adequando-o às tuas necessidades;
c) Modificar o método “doBasicTask” adequando-o às
necessidades atuais.
8. Que conceito garante que objetos de classes diferentes
partilhem métodos?
a) Polimorfismo;
b) Herança;
c) Abstração.
66
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

9. Em orientação a objectos:
a) Todo e qualquer objeto pode invocar o método “equals”
visto que a superclasse Object implementa este método;
b) Toda e qualquer classe de Objectos possui um construtor
sem parâmetros;
c) Todo e qualquer método de uma classe de objectos pode
ser invocado sobre todo e qualquer objeto dessa classe.
10. Se uma superclasse define um método como “private”, a
subclasse poderá reescrever este método como public.
a) Não, porque métodos privados não podem ser
reescritos;
b) Sim, porque a subclasse pode modificar tal método para
se adequar às suas necessidades;
c) Nenhuma opção está correta.

Respostas: 1-F, 2-F, 3-V, 4-F, 5-F, 6-a, 7-b, 8-b, 9-a, 10-a

Unidade temática 2.3: Polimorfismo e abstração.

Introdução

O polimorfismo faz parte dos pilares da programação orientada a


objetos; junto com a abstração permite construir aplicações complexas
e abrangentes com bastante simplicidade e transparência. Só para se
ter uma ideia, estes dois conceitos juntos são as fundações dos grandes
frameworks de desenvolvimento daí que é importante que os mesmos
sejam compreendidos por quem deseja se tornar desenvolvidor de
software. Nesta unidade temática 2.3 serão apresentadas de uma
forma simples as bases para a compreensão do polimorfismo e
abstração.
Ao completar esta unidade temática, você deverá ser capaz de:

▪ Explicar: o conceito de polimorfismo;


▪ Compreender: em que situações o conceito polimorfismo pode
ser aplicado;
Objectivos ▪ Explicar: o conceito de abstração e como o mesmo é concebido;
específicos ▪ Aplicar: corretamente os conceitos de polimorfismo e abstração
na conceção de aplicações abrangentes e transparentes.

67
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

▪ Explicar: em que situações se deve abstrair usando herança ou


usando interface.

O problema
Considere o modelo de classes apresentado na unidade temática 2.2. O
modelo em causa é composto por três classes de objetos,
nomeadamente, a superclasse Conta, e as subclasses ContaOrdem, e
ContaPrazo.
Vamos dotar as nossas classes de capacidades de persistência de dados
em ficheiro: a saber (1) descarregamento de dados do objeto no ficheiro
e (2) carregamento dos dados do objeto a partir do ficheiro. Vamos
incluir dois métodos na superclasse Conta, o método
“unloadToCurrentLineOfFile” que descarrega os dados da conta no
ficheiro e o método “loadFromCurrentLineOfFile” que recupera os
dados do objeto a partir da linha corrente do ficheiro. Vamos ainda
incluir um método que permite fazer um “clone” da conta, chamaremos
esse método “clone”. Uma vez que as subclasses da classe Conta
possuem algumas particularidades, iremos rescrever os métodos
mencionados nas subclasses ContaOrdem e ContaPrazo3.
Nas figuras seguintes estão representadas as classes mencionadas
anteriormente. Note que alguns elementos destas classes foram
omitidos, mas eles podem ser encontrados em detalhe na unidade
temática 2.2.

3
O manejo de ficheiros está fora do contexto desta unidade. Caso não tenha
conhecimentos relacionados com o acesso e escrita de dados em ficheiros de texto
considere fazer leitura da unidade III.

68
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 39: A classe Conta com habilidades para persistir dados


Note que alguns elementos da classe Conta foram ocultados,
nomeadamente (ponto 1) os atributos, o construtor com 3 parâmetros
e todos os outros métodos apresentados na unidade temática 2.2. Note
ainda que foram adicionados novos elementos, a saber (ponto 2)
construtor de um parâmetro, (ponto 3) o método “clone” que cria e
retorna uma cópia da conta, (ponto 4) o método
“unloadToCurrentLineOfFile” que escreve os dados da conta a partir da
linha corrente do “buffer” recebido pelo parâmetro e (ponto 5) o
método “loadFromCurrentLineOfFile” que recupera os dados da conta
a partir da linha corrente do “buffer”;

69
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 40: A classe Conta ordem


Nesta classe acrescentou-se os seguintes métodos: (1) o construtor de
um parâmetro; (2) for reescrito o método “clone” que faz uma cópia da
conta e a retorna; (3) foi reescrito o método
“unloadToCurrentLineOfFile” que escreve no ficheiro os dados da conta
mais a informação do regime e (4) foi reescrito o método
“loadFromCurrentLineOfFile” que recupera do ficheiro os dados da
conta mais a informação do regime.

70
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 41: A classe ContaPrazo

Nesta classe, foi igualmente adicionado o construtor de um parâmetro


e reescritos os métodos “clone”, “loadFromCurrentLineOfFile” e o
“unloadToCurrentLineOfFile”.
Com base neste modelo que acabamos de criar, vamos conceber um
programa que permita (1) criar dois objetos, um do tipo ContaOrdem e
outro do tipo ContaPrazo, (2) depositar 1000 em cada uma das contas
e (3) descarregar os dados das contas, respetivamente nos ficheiros
“contas_ordem.txt” e “contas_prazo.txt”. A solução para este problema
ficaria como ilustrado na figura a seguir:

71
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 42: Criação e manipulação dos objeto do tipo "ContaOrdem" e "Conta Prazo"
Visitando os ficheiros criados notamos que o conteúdo dos mesmos é
semelhante ao que está apresentado na figura abaixo.

Figura 43: Aparência final dos ficheiros "conta_ordem.txt" e "conta_prazo.txt"

Nota-se algumas diferenças entre os dois ficheiros, (1) o saldo final no


ficheiro “contas_prazo.txt” é maior em relação ao saldo no outro
ficheiro, e o ficheiro “contas_prazo.txt” apresenta duas linhas que não
aparecem no ficheiro “contas_ordem.txt” e este por sua vez apresenta
uma linha que não aparece no outro ficheiro. Como se explicam estas
diferenças? A primeira diferença já havia sido explicada na unidade
temática número 2 e tem a ver com o facto de a conta a prazo
acrescentar ao saldo 3% do valor do depósito, a cada depósito. A
segunda diferença tem a ver com o fato de as classes a ordem
acrescentarem mais uma linha ao

72
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

ficheiro quando os dados destes são descarregados num ficheiro e as


contas a prazo acrescentam mais duas linhas.
Agora considere o código apresentado na figura seguinte e preste
atenção a instrução em destaque no ponto 1.

Figura 44: Exemplo de polimorfismo

Será que a atribuição feita no ponto 1 está correta? Esta atribuição


parece não estar correta, pois estamos a fazer uma “atribuição” de uma
instância de “ContaPrazo” a uma referência do tipo “Conta”. Mas será
que “ContaPrazo” não é uma “Conta”? ContaPrazo é sim uma Conta!
Logo esta atribuição é correta. Nesta linha fizemos com que a variável
‘conta’ referenciasse o “objeto” ‘cp’, esta última referencia um objeto
do tipo ContaPrazo, logo, tanto a variável ‘conta’ como ‘cp’ referenciam
o mesmo objeto. Temos aqui o que se chama, em programação
orientada a objetos, de Polimorfismo.

Definição
Polimorfismo é a capacidade de um objeto poder ser referenciado de
várias formas. No nosso exemplo referimo-nos a “conta a prazo” como
“conta”. Afinal toda a “conta a prazo” é também uma “conta”!
E qual será o resultado da invocação do método “depositar” em
destaque no ponto 2? O resultado será o incremento de 3% do valor do
depósito ao saldo conforme definido na classe ContaPrazo! Isso soa
estranho pois estamos a invocar o método sobre uma variável do tipo
Conta! Mas dissemos antes que esta variável faz referência a um objeto
do tipo ContaPrazo, logo, o método invocado será o definido nesta
classe (ContaPrazo).
O polimorfismo adiciona poder à programação orientada a objetos!

73
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Benefícios do polimorfismo
Considere que se pretende criar uma aplicação bancária com
mecanismos de persistência de dados de contas bancárias em ficheiros
de texto. Para além dos métodos habituais de processamento de
operações bancárias (para a criação de contas, depósitos,
levantamentos, transferência e consulta) precisaríamos de métodos
para escrever/atualizar dados no ficheiro e recuperar dados do ficheiro.
Vamos chamar estes métodos respetivamente de “saveToFile”,
“updateOnFile” e “loadFromFile”. Para tornar o entendimento fácil, a
aplicação em causa ira criar duas contas [ContaOrdem e ContaPrazo],
armazena-las no ficheiro, de seguida irá recuperar as contas, depositar
1000 em cada uma delas e finalmente atualizar os dados no ficheiro.
Cada conta será registada no seu respetivo ficheiro.
A seguir são apresentados os métodos desta aplicação; primeiro
apresenta-se o “main” e métodos relacionados, mais adiante o detalhe
dos métodos “saveToFile”, “updateOnFile” e “loadFromFile”.

Figura 45: Aplicação complexa (continuação na próxima figura)

74
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Na figura acima apresenta-se a primeira parte da App2, nesta parte está


apresentado o “main” o qual invoca dois métodos, o método
“criarContas”, que cria as duas contas e as armazena em ficheiros, e o
método “efectuarDeposito”, que recupera as contas do ficheiro,
deposita 1000 em cada uma delas e finalmente, atualiza os seus dados
no ficheiro. Voltaremos a nossa atenção a esta parte mais tarde. Para já
é apresentada a 2ª parte desta aplicação que é composta pelos
métodos: “saveToFile”, que regista os dados da conta no ficheiro,
“loadFromFile” que recupera a conta do ficheiro e a retorna e
“updateOnFile” que atualiza os dados da conta no ficheiro.

Figura 46: Aplicação complexa (continuação)

Preste atenção nas partes destacadas, as mesmas serão mencionadas


através dos números associados aos respetivos retângulos.
O método criarContas (já mencionado antes) cria duas instâncias [ou
objetos], uma do tipo ContaOrdem e outra do ContaPrazo, com as
referências contaOrdem e contaPrazo, respetivamente (ponto 2). No
ponto 3 do código é criada uma segunda referência ao “objeto”
contaOrdem; referimo-nos a isto como
75
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Polimorfismo! A seguir as duas instâncias são descarregados nos


respetivos ficheiros (pontos 5 e 7). Note que usamos o mesmo método
[saveToFile] para descarregar ambos os objetos apesar de serem de
“tipos diferentes”, alias o método “saveToFile” recebe pelo parâmetro
uma referência a “Conta”. Esta é uma vantagem do polimorfismo, pois
com o mesmo método conseguimos tratar dois objetos de “tipos
diferentes”. Note que antes de descarregarmos os objetos primeiro
tentamos recuperá-los do ficheiro (ponto 4 e 6) e só os descarregamos
se eles ainda não estiveram lá no ficheiro.
Agora preste atenção ao método “saveToFile”, concretamente no
ponto 12. Neste ponto é invocado, sobre a instância, o método
“unloadToCurrentLineOfFile” com intuito de descarregar os dados da
conta no ficheiro. Não se esqueça que o método “saveToFile” uma vez
é lhe passado uma referência a “ContaOrdem” e outra vez é lhe passado
uma referência a “ContaPrazo”. A questão é, “De qual classe [Conta,
ContaPrazo ou ContaOrdem] será invocado o método
unloadToCurrentLineOfFile”? Em tempo de execução, o compilador irá
decidir de qual destas classes o método será invocado dependendo do
tipo de objeto que lhe for passado, se o objeto for “contaOrdem” o
mesmo será invocado sobre a classe “ContaOrdem” visto que esta
classe reescreveu o método em questão; se o objeto for “contaPrazo”
o mesmo será invocado sobre a classe “Conta”. O método saveToFile
tem a capacidade de armazenar os dados no ficheiro no formato
definido pela instância concreta de conta. Se no futuro surgir um novo
tipo de instâncias de Conta [digamos ContaEspecial] com seu formato
de armazenamento de dados, as mesmas poderão ser tratadas pelo
mesmo método saveToFile desde que a classe ContaEspecial reescreva
o método “unloadToCurrentLineOfFile” e incorpore as suas próprias
regras de armazenamento de dados.
O que acabou de ser explicado também é válido para os métodos
“loadFromFile” e “updateOnFile”. Ambos recebem referência de Conta,
que pode ser concretamente do tipo ContaOrdem ou ContaPrazo.
Vamos prestar atenção ao método “loadFromFile”; ele tem como
objetivo recuperar os dados de uma conta bancária armazenada no
ficheiro. Não se esqueça que o formato de armazenamento de ambas
as contas é diferente. A partir do método “efectuarDeposito” [ponto 9]
pode se notar que o método loadFromFile é lhe passado primeiro uma
referência a uma ContaOrdem e depois é lhe passado uma referência a
“ContaPrazo”. O método “loadFromFile” começa por verificar [no
ponto 13] se o ficheiro existe ou não; caso não exista assume-se que a
conta não pode estar no ficheiro, logo retorna-se “null”4; a seguir é

4
O “null” é o mesmo que vazio!

76
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

aberto o ficheiro e é associado ao BufferedReader. No ponto 14 faz-se


uma cópia do objeto recebido pelo parâmetro o qual é armazenada na
variável “contaFromFile”, esta variável é usada para carregar a conta na
linha corrente do ficheiro. O ficheiro é “varrido” por meio de um ciclo
“while”. Repare que a cada iteração é invocado [sobre a variável
“contaFromFile”] o método “loadFromCurrentLineOfFile” (ponto 16)
que recupera os dados a partir da linha corrente do ficheiro e a carrega
para o objeto “contaFromFile”. Dependendo da instância sobre a qual
este método for invocado, ou irá carregar os dados da “ContaPrazo” ou
“ContaOrdem” visto que o método “loadFromCurrentLineOfFile” foi
reescrito nas duas classes [ContaOrdem e ContaPrazo]. O método
“loadFromFile” é capaz de recuperar qualquer instância de qualquer
outra subclasse de Conta, desde que esta implemente as suas regras de
recuperação de dados a partir da linha corrente.

O polimorfismo – a conclusão
Até aqui foi apresentado o conceito polimorfismo.
Polimorfismo é um conceito que se aplica entre uma classe e suas
subclasses. As instâncias das subclasses podem ser referenciadas por
variáveis de superclasse, o oposto não é possível.
O polimorfismo permite abstrair funcionalidades para classes
inicialmente não existente. Por exemplo, no problema tratado
anteriormente criamos o método “saveToFile” cuja sua função é
armazenar os dados de uma conta no ficheiro; no entanto, cada tipo de
conta pode ter o seu formato de armazenamento de dados, mesmo
assim, este método continua a funcionar para todos eles. Se no futuro
surgirem novos tipos de instância, os mesmo poderão ser tratados por
este método sem a necessidade de o método ser remexido. Sem
polimorfismo teríamos de criar um método “saveToFile” para cada tipo
de conta existente!

Classes abstratas e Abstração


Graças ao polimorfismo podemos fazer referência aos objetos das
subclasses com variáveis do tipo da superclasse. No exemplo anterior,
fizemos referência a “ContaOrdem” e “ContaPrazo” com variáveis de de
tipo Conta; isso trouxe um ganho significativo, pois (por exemplo) com
um único método (saveToFile) foi possível responder a um problema
para as várias subclasses da classe Conta. Voltemos a nossa atenção ao
problema levantado no início do capítulo sobre herança (Unidade
temática 2.2). Com que objetivo criamos a classe Conta? O objetivo era
agrupar as características comuns às classes de contas bancárias,
ContaOrdem, e ContaPrazo, que são as classes que importa estudar;
logo, a classe Conta é uma classe auxiliar que foi criada justamente para

77
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

contornar um problema, o problema de repetição de código. Há bocado


vimos que esta classe também nos ajuda a conseguir polimorfismo. Mas
será que em algum momento na nossa aplicação haverá necessidade de
criar um objeto do tipo Conta? A resposta é “não!” pois, o que está em
estudo são as duas classes: ContaOrdem e ContaPrazo. Logo não faria
sentido algum a criação de uma instância da classe Conta. O uso de
instâncias da classe Conta pode gerar situações inesperadas que
poderiam incorrer em inconsistência de dados.
O java possui um mecanismo para inibir a criação de instância de uma
classe. Isso é conseguido definindo a classe como abstrata.
Uma classe abstrata é uma classe que não pode ser instanciada, ela
funciona como “esboço” de todas as suas subclasses. A classe abstrata
é definida usando a palavra reservada “abstract”, conforme ilustrado
abaixo.

Figura 47: A classe Conta definida como abstrata


A partir deste momento, torna-se impossível criar um objeto do tipo
Conta! Qualquer tentativa de instanciar o Conta irá gerar um erro de
compilação. Note que o método “clone” da classe Conta (ponto 2) agora
possui um erro pois o mesmo instancia a classe Conta.
Mas qual é a importância de classes abstratas? A grande vantagem de
classes abstratas é a possibilidade de adicionar métodos abstratosnelas.
Um método abstrato é nada mais que uma simples declaração de

78
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

método sem nenhuma implementação. A implementação deverá ser


feita em cada uma das classes filhas da classe em causa. E qual é
vantagem disso?
Voltemos a nossa atenção ao modelo de classes apresentado no início
desta unidade temática. O nosso modelo é constituído por uma
superclasse e duas subclasses desta, ambas reescreveram os métodos
“loadFromCurrentLineOfFile”, “unloadToCurrentLineOfFile” e “Clone”,
de tal maneira que se adeque às necessidades de cada uma [em termos
de recuperação de dados a partir de um ficheiro, escrita de dados no
ficheiro e cópia dos dados]. O que aconteceria se se adicionasse uma
nova subclasse, digamos, ContaEspecial, cujo formato de
armazenamento de dados fosse diferente? Imagine o que iria acontecer
se o criador desta classe se “esquecesse” de reescrever por exemplo, o
método “loadFromCurrentLineOfFile”! Erradamente, a forma de
recuperação de objetos da ContaEspecial seria herdada a partir da
superclasse “Conta” o que poderia gerar resultados errados pois, o
formato de armazenamento de dados pode ser diferente.
Quando uma superclasse define um método como abstrato, o
compilador obriga a sua implementação em todas as suas subclasses
(não abstratas). Este efeito evita o “esquecimento” de reescrita de
métodos por parte dos programadores que fazem a extensão de classes
com métodos que precisam de ser reescritos.
Um método abstrato é definido apenas com a parte da assinatura do
método, sem nenhum corpo. Abaixo definem-se os métodos “clone”
“loadFromCurrentLineOfFile” e “unloadToCurrentLineOfFile” como
abstrato.

79
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 48: A classe Conta com os métodos "clone", "loadFromCurrentLineOfFile" e


"unloadToCurrentLineOfFile" como abstrato
A partir de já, qualquer subclasse da classe Conta deverá
obrigatoriamente implementar os métodos “clone”,
“loadFromCurrentLineOfFile” e “unloadToCurrentLineOfFile”, salvo se
esta subclasse também for abstrata.
Nas figuras seguintes são apresentadas as implementações destes
métodos nas subclasses ContaOrdem e ContaPrazo.
Abaixo são apresentadas as implementações destes métodos nas
subclasses ContaOrdem e ContaPrazo.

80
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 49: Implementação dos métodos abstratos da classe conta na classe


ContaOrdem

Figura 50: Implementação dos métodos abstratos da classe conta na classe


ContaPrazo

Interface
Até aqui foram apresentados os conceitos relacionados com herança,
suas vantagens e a possibilidade que ela nos dá de aplicar polimorfismo.

81
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Abordamos também as vantagens do uso de classes e métodos


abstratos.
Lembras quais são as vantagens do polimorfismo e da “abstração”?
Reveja! A seguir é introduzido o conceito “interface”.
Voltemos a nossa atenção a aplicação App02 apresentada nesta
unidade temática. Neste exemplo criou-se uma aplicação com
habilidades de escrever e recuperar dados de contas em ficheiros de
texto. Fazendo uso de polimorfismo, foi possível usar os mesmos
métodos para tratar da persistência de dados de qualquer subclasse da
classe Conta. Os métodos em causa são “saveToFile”, “loadFromFile” e
“updateOnFile”. Repare que estes métodos usam de habilidades das
instâncias das subclasses da classe Conta para escrever e ler do ficheiro,
respetivamente os métodos “unloadToCurrentLineOfFile” e
“loadFromCurrentLineOfFile”. A forma como cada subclasse de Conta
persiste os seus dados é diferente em cada uma das classes, mas o
funcionamento dos métodos da nossa aplicação [“saveToFile”,
“loadFromFile” e “updateOnFile”] é igual, sempre! Se no futuro
surgirem outras subclasses da classe Conta, as suas instâncias poderão
ser persistidas usando estes métodos pois com a introdução da
abstração todas elas são obrigadas a implementar os métodos
“unloadToCurrentLineOfFile” e “loadFromCurrentLineOfFile”; estes
são os únicos métodos necessários para que a persistência ocorra
através dos métodos da “App02”. Esta é a ideia da abstração! Conceber
soluções que possam funcionar com “instâncias futuras”. Voltaremos a
falar sobre a abstração mais tarde.
A solução descrita no parágrafo anterior parece adequar-se
perfeitamente ao nosso problema: “A persistência de dados de
qualquer tipo de conta bancária”. Vamos agora criar um “motor” de
persistência de dados de contas. Basicamente este motor é uma classe
que agrupa os três métodos de persistência, nomeadamente
“saveToFile”, “updateOnFile” e “loadFromFile”; nossa intenção é ter
uma classe que poderá ser usada em qualquer Aplicação para persistir
os dados da Conta. Vamos chamar esta classe de
“MotorDePersistencia”.

82
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 51: "Motor" de persistência de dados

Abaixo apresenta-se um exemplo duma aplicação que faz uso deste


“motor” para persistir os dados de conta do tipo ContaOrdem. Uma
aplicação similar pode ser criada para persistir contas do tipo
ContaPrazo ou qualquer outra subclasse da classe Conta. Temos um
“motor poderoso” capaz de trabalhar com qualquer que seja o tipo de
conta, seja as contas atualmente existentes [ContaOrdem e
ContaPrazo] ou qualquer outro tipo de conta que surgir no futuro.

83
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 52: Exemplo de aplicação que faz uso do "motor de persistência"

Agora vamos complicar um pouco a nossa solução! Vamos supor que


estivéssemos interessados em persistir instâncias da classe Stock
apresentada no tema 1 deste manual. Será que poderíamos usar o
nosso “Motor de Persistências” para persistir instâncias de Stock? A
resposta é não! E o que seria necessário para podermos usar este
motor? Conforme visto, os métodos do nosso “Motor de Persistência”
suportam instâncias de subclasses da Conta, sendo assim, a forma mais
fácil de reaproveitar as funcionalidades do motor seria fazer com que a
classe Stock fosse “filha” de Conta. Mas será que essa solução é ótima?
Claro que esta solução resolveria o nosso problema, mas a mesma traz
consigo outros problemas! O grande problema é que o relacionamento
que estabeleceríamos entre o Stock e Conta seria meio “esquisito”!
Na verdade, este relacionamento violaria as regras básicas de Herança
nomeadamente, a regra de "100 porcento" e a regra "…é do tipo de…".
A primeira regra sugere que, se uma classe estende outra, então todos
os atributos e métodos da superclasse devem se aplicar a ela. Asegunda
regra é uma simples forma de testar se a Herança é válida; elaé expressa
em simples palavras “a classe ‘B’ é do tipo ‘A’”. Se esta frasenão fizer
sentido é sinal de a Herança entre ‘B’ e ‘A’ é desnecessária e poderá
trazer problema de manutenção. Por exemplo, na Herança
ContaOrdem-Conta (ContaOrdem estende Conta), a frase “a
ContaOrdem é do tipo Conta” faz sentido; mas na Herança Stock-Conta
(Stock estende Conta) a frase “Stock é do tipo Conta” não faz sentido,
logo esta herança não é válida!

84
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Nosso objetivo era usar de polimorfismo e garantir que podemos


reutilizar o motor de persistência para persistir stock. Será que vamos
recriar um motor de persistência para persistir Stock? Isso seria
desagradável pois este novo motor seria muito parecido ao motor já
existente, logo teríamos repetição de código. O que nos falta é a
possibilidade de fazermos referência ao Stock da mesma forma como
fazemos referência as subclasses da Conta.
E se pudéssemos ter uma forma comum de fazer referência tanto ao
Stock como as subclasses da Conta? Nosso problema com certeza seria
resolvido pois iriamos reescrever o “Motor de Persistências” de tal
maneira que suporte essa nova forma de referência. Lembra-se quais
são os requisitos para que uma determinada instância seja persistida
pelo “Motor de Persistência”? O único requisito é que tenha
implementado os métodos “clone”, “unloadToCurrentLineOfFile” e
“loadFromCurrentLineOfFile”.
Existe em java uma forma de garantir que um conjunto de entidades
[classes] tenha [obrigatoriamente] certas habilidades em comum sem
que estas [entidades] sejam subclasses da mesma classe. Isso é
conseguido por meio de interface.
Definição de Interface
Uma interface é uma classe que define um conjunto de habilidades que
devem ser implementadas por todas as classes que precisam ser
tratadas duma determinada forma [definida pela interface]. Usando o
mecanismo de interface é possível referenciar instâncias de classes
diferentes da mesma forma sem que estas sejam descendentes da
mesma superclasse e conseguindo dessa forma "múltiplas
possibilidades de polimorfismo". A semelhança de métodos abstratos,
a interface simplesmente abstrai as funcionalidades sem implementá-
las, a implementação é feita nas classes que implementam esta
interface. Uma classe de objetos pode implementar múltiplas
interfaces!
Exemplo 3
Como este mecanismo resolve o problema levantado? No nosso
problema estávamos interessados em poder referenciar, ContaOrdem,
ContaPrazo e Stock da mesma forma para poder usar os métodos do
nosso “Motor de Persistência” para persistir os dados destas entidades.
Usando Herança fracassamos; mas usando interfaces seremos bem-
sucedidos pois conseguiremos os nossos intentos: referenciar as
instâncias das três classes da mesma forma.
Para isso vamos criar uma interface que deverá ser implementada por
todas as classes que precisem persistir os seus dados em ficheiros de
texto. Vamos chamar a interface de “Gravável”. O código desta
interface fica assim:

85
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 53: Interface "Gravável" que abstrai qualquer objeto gravável em ficheiro

Note que a interface define apenas as assinaturas dos métodos e não a


implementação destes (tal como acontece com métodos abstratos). A
implementação dos métodos deverá ser feita obrigatoriamente nas
classes que a implementam [salvo se estas forem abstratas]
Vamos reescrever as nossas classes de tal maneira que estas
implementem a interface “Gravável”.

Figura 54: A classe "ContaOrdem" implementando a interface "Gravável"


A classe “ContaPrazo” deverá igualmente ser modificada para
implementar a interface “Gravavel”.

86
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 55: A classe Stok implementando a interface Gravavel


Note que a classe Stock, a partir do momento que implementa a interface
“Gravavel” ela é obrigada a implementar os 3 métodos definidos na
interface.

Já podemos nos referir a cada uma destas entidades como Gravável.


Por exemplo, podemos fazer, sem nenhum problema, as seguintes
referências

Figura 56: Instância de Stock e ContaOrdem sendo referenciados por variáveis do tipo
Gravavel

Agora, vamos reescrever o nosso motor de persistência para ser


compatível com qualquer que seja objeto “Gravável”.

87
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 57: Motor de Persistência abstraindo o Gravável

Nosso “motor de persistência” agora suporta objeto “Gravável” [ponto


1]. Este objeto poderá ser instância de qualquer classe que implemente
a interface “Gravavel”. Ai está o poder do uso de interface e de toda
abstração. Repare que o método “saveToFile” foi concebido para
armazenar os dados de objetos no ficheiro, mas a forma como cada
objeto armazena os seus dados pode variar; por isso, essa parte foi
“abstraída” pelo método “unloadToCurrentLineOfFile” [ponto 2]
definido na interface. Qualquer classe que quiser que o motor de
persistência persiste os seus dados, terá de indicar neste método como
os dados dos seus objetos são persistidos. O mesmo acontece com a
recuperação de dados. Todas as classes que implementam a interface
“Gravavel” devem indicar como os dados do objeto são recuperados a
partir da linha corrente do ficheiro, isso é feito dentro do método
“loadFromCurrentLineOfFile”. O método do nosso motor para a
recuperação de dados [loadFromFile] não precisa saber como
recuperar os dados de cada novo tipo de objeto que surgir, ele

88
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

simplesmente assume que qualquer “Gravável” fará isso por si [ponto


4].
Resumindo, o nosso motor de persistência pode ser comparado a um
usuário de “controlo remoto” (remote) de um aparelho eletrónico. O
usuário, sabe manejar “remotes” de vários aparelhos, mas não sabe
como cada aparelho implementa os mecanismos de controlo. Por
exemplo, ele sabe que o botão “on/off” liga/desliga qualquer aparelho,
mas nunca se preocupa em saber como isso acontece dentro do
dispositivo [detalhes de implementação]. O remote fornece uma
interface para a manipulação do aparelho, esta interface é a mesma
para diferentes dispositivos, mas a forma como cada dispositivo
implementa as funcionalidades é diferente. Nosso motor de
persistência não sabe como cada objeto armazena ou recupera seus
dados no ficheiro, ele simplesmente sabe que ao invocar, por exemplo,
o método “unloadToCurrentLineOfFile”, os dados serão armazenados
no ficheiro, e ao invocar o método “loadFromCurrentLineOfFile” os
dados serão recuperados!
Vejamos por fim o nosso motor de persistência em ação. No exemplo
seguinte, o motor é usado para persistir “Stock” e “ContaOrdem”.

Figura 58: Aplicação do Motor de persistência para persistir "Stock" e "ContaOrdem"

Sumário
Nesta unidade temática 2.3 estudamos com alguma profundidade mais
dois pilares da programação orientada a objetos, nomeadamente,
polimorfismo e abstração. Vimos que a abstração é um conceito chave
para a construção de aplicações fidedignas e de fácil leitura. Tal é
conseguido tornando o acesso aos atributos da classe de objetos
restrito e controlado. Usando o
89
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

encapsulamento garantimos que os dados do objeto serão manejados


a partir do interior do objeto e este fornece uma interface de acesso
tanto às operações sobre os dados como aos atributos do mesmo.
O polimorfismo e a abstração são conceitos que andam lado-a-lado;
estes dois conceitos permitem conceber aplicações complexas de forma
transparente na medida em que permitem antecipar soluções para
problemas futuros. O polimorfismo favorece a abstração na medida em
que ele permite que uma instância seja ferenciada usando referências
de múltiplos tipos.
A abstração permite conceber soluções a alto nível, concentrando-se
nos aspetos essenciais da solução e deixando os detalhes específicos a
cada caso para classes específicas. A abstração garante que soluções
criadas no passado sejam uteis na resolução de problemas presentes ou
futuros, visto que a solução é concebida de forma abstrata evitando
“amarrar” a solução a casos concretos. No exemplo abordado nesta
unidade temática, a nossa solução abstrai o armazenamento e
recuperação de dados de um objeto do ficheiro. Note que essa
funcionalidade é abstrata dado que cada objeto pode ter seu formato
de armazenamento de dados e consequentemente a sua recuperação
será também diferente, daí que a nossa solução não se “amarrou” a um
caso específico, alargando assim o universo de aplicação da solução.
Como cada objeto escreve/recupera os seus dados é tido aqui como
algo abstrato e isso foi abstraído pela interface “Gravável”. Neste caso
“Gravável” é algo abstrato: “Qualquer coisa que seja Gravável em
ficheiro de texto”. O nosso motor foi construído tendo isso em
consideração uma entidade abstrata que precise ser persistida. A
abstração pode ser conseguida por meio de classes abstratas ou por
meio de interfaces. O uso de classes abstratas restringe a abstração a
classes da mesma família ao passo que o uso de interfaces é mais
abrangente.

Exercícios de autoavaliação
Perguntas
1. Justifique a necessidade do uso do encapsulamento.
2. Defina o conceito abstração em programação orientada à
objetos;
3. Defina o conceito polimorfismo.
4. O que é uma classe abstrata e quais problemas resolve?
5. O que é uma interface e que vantagens as mesmas
introduzem no processo de programação?
Respostas:
1. O encapsulamento é um conceito através do qual os
programas são organizados de tal maneira que os dados

90
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

sejam manipulados de forma controlada a partir de


determinados pontos do programa. Esta forma de
organização evita que os dados sejam manipulados de forma
descontrolada evitando possíveis inconsistências de dados
2. A abstração é uma técnica que permite conceber soluções a
alto nível, concentrando-se nos aspetos essenciais da
solução e deixando os detalhes específicos a cada caso para
classes específicas. A abstração garante que soluções criadas
no passado sejam uteis na resolução de problemas
presentes ou futuros, visto que a solução é concebida de
forma abstrata evitando “amarrar” a solução a casos
concretos.
3. Polimorfismo é a capacidade de um objeto poder ser
referenciado de várias formas; isto é, a mesma instância
poder ser referenciada por variáveis de múltiplos tipos.
4. Uma classe abstrata é uma classe que não pode ser
instanciada. Classes abstratas permitem a introdução de
métodos abstrato os quais garantem que cada subclasse
possa implementar determinado comportamento
adequando-o às suas próprias necessidades.
5. Uma interface é uma classe que define um conjunto de
habilidades que devem ser implementadas por todas as
classes que precisam ser tratadas duma determinada forma
[definida pela interface]. Usando o mecanismo de interface
é possível referenciar instâncias de classes diferentes da
mesma forma sem que estas sejam descendentes da mesma
superclasse e conseguindo dessa forma "múltiplas
possibilidades de polimorfismo". A semelhança de métodos
abstratos, a interface simplesmente abstrai as
funcionalidades sem implementá-las, a implementação é
feita nas classes que implementam esta interface. Uma
classe de objetos pode implementar múltiplas interfaces!

Exercícios para avaliação


Perguntas
Nos números seguintes, assinale a alternativa mais correta.
1. Qual das seguintes declarações descreve melhor a abstração?
a) Conceber soluções flexíveis hoje, adaptáveis a problemas
futuros;
b) Conceber soluções hoje, para problemas complexos de
amanhã;
c) Conceber soluções complexas hoje, para simplificar
problemas de amanhã.
2. Qual das seguintes instruções aplica o conceito de
polimorfismo?
91
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

a) “A a = new B();” se a classe “A” for filha de “B”;


b) “I i = new C();” se “I” for uma interface;
c) “K k = new T()” se a classe “K” e a classe “T” implementarem
a mesma interface.
3. Se “Automovel” é uma interface que define os métodos
“acelerar” e “travar”, então se a classe “Carro” implementa
“Automovel”
a) Está garantido que qualquer objeto do tipo “Carro” poderá
invocar o método “travar”;
b) Está garantido que qualquer objeto do tipo “Automóvel”
pode ser referenciado por variáveis do tipo “Carro”;
c) Está garantido que qualquer carro tem a possibilidade
travar.
4. Considere a classe “AbstractMethodError” que estende a classe
“IncompatibleClassChangeError”; pode se dizer que:
a) A classe “AbstractMethodError” é obrigada a implementar
todos os métodos implementados na classe
“IncompatibleClassChangeError”
b) A classe “AbstractMethodError” herda os métodos e
atributos não “private” da classe
“IncompatibleClassChangeError”
c) A classe “IncompatibleClassChangeError” herda os métodos
e atributos não “private” da classe “AbstractMethodError”
5. Em qual das seguintes situações temos exemplo de
polimorfismo?
a) Um método que, pelo parâmetro, ora recebe um aluno, ora
um professor ora um diretor de turma…
b) Um método que, pelo parâmetro, ao mesmo tempo recebe
um aluno, um professor e um diretor de turma;
c) As duas opções estão corretas.
6. Se “Automovel” é uma interface que define os métodos
“acelerar” e “travar”, então se a classe “Carro” implementa
“Automovel”
a) Está garantido que qualquer carro tem a possibilidade
travar.
b) Está garantido que qualquer objeto do tipo “Carro” pode ser
referenciado por variáveis do tipo “Automóvel”
c) Está garantido que qualquer objeto do tipo “Automóvel”
pode ser referenciado por variáveis do tipo “Carro”;
7. Se a classe “Carro” implementa a interface “Automóvel” então
a) A interface “Automóvel” deve possuir todos os métodos da
classe “Carro”;
b) A classe “Carro” deve implementar todos os métodos
implementados na interface “Automóvel”
c) A classe “Carro” deve implementar os métodos assinados na
interface “Automóvel”

92
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

8. Se a classe abstrata “Veiculo” assina o método “public abstract


String locomover()” então a seguinte instrução é correcta;
a) System.out.println((new Veiculo()).locomover());
b) System.out.println((new Tractor()).locomover()); se Tractor
for filha de “Veiculo”
c) System.out.println(Veiculo.locomover());
9. Se a classe “Carro”, e “Motorizada” implementam a interface
“Automóvel”, então:
a) A instrução “Carro c = new Motorizada ();” é correta, pois
carro e motorizada são da mesma “família”.
b) A instrução “Motorizada moto = new Automovel();” é
correta e temos aqui o que se chama polimorfismo.
c) A instrução “Automóvel a = new Automóvel();” não pode
estar correta!
10. Se a classe “CF1” e a classe “CF2” são filhas da classe “C” então
pode-se dizer com certeza que:
a) Os objectos do tipo “C” podem ser referenciados por
variáveis do tipo “CF1” ou “CF2”; a isso chama-se
polimorfismo!
b) Os objectos do tipo “CF2” podem ser referenciados por
variáveis de tipo “C”; a isso chamamos polimorfismo!
c) Os objectos do tipo “CF1” podem ser referenciados por
variáveis do tipo “CF2”; isso chama-se polimorfismo.

Respostas: 1a, 2b, 3a, 4b, 5a, 6b, 7c, 8b, 9c, 10b

Execícios do Tema

Exercios de autoavaliação
Perguntas
1. Relacione os conceitos abstração e polimorfismo;
2. Quais são os benefícios que advém do uso de abstração e
polimorfismo?
3. Justifique a necessidade do uso de classes abstratas;
4. Crie uma classe de objetos [“Estudante”] para representar o
estudante na cadeira de Programação Avançada em Java; a
classe em causa deverá implementar a interface
[“Gravável”] apresentada na unidade 2.3. Suponha que o
estudante é descrito por: código, nome completo, e notas de
três avaliações [teste 1, teste 2 e trabalho]. A classe em
causa deverá ter as seguintes características:
• Um construtor com 5 parâmetros representando os
atributos da classe;

93
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

• Um construtor com um parâmetro, a saber, código


do estudante;
• Um construtor com dois parâmetros,
nomeadamente: código e nome completo do
estudante;
• O método “equals”; considere que dois objetos do
tipo estudante são iguais se tiverem códigos iguais;
• O método “public double calculaMedia()” que calcula
a nota de frequência dada pela formula “NF=0.3*T1
+ 0.3*T2 + 0.4*TR” onde: T1 e T2 são as notas nos
testes 1 e teste 2, TR é a nota do trabalho;
• O método “public String determinaSituacao()”, que
retorna “EXCLUIDO” se a nota de frequência do
estudante for inferior a 9.5 ou “ADMITIDO” no caso
contrário;
• O método “toString”;
• Logicamente terás de implementar os métodos
definidos na interface para a persistência de dados.
Considere que os dados do estudante são
armazenados no ficheiro no formato vertical em que
as colunas estão separadas por hífen.
5. Na unidade temática 2.3 foi apresentado o motor de
persistências genérico, o qual tem habilidades de persistir
qualquer instância de classe que implemente a interface
“Gravável”. No número anterior criaste a classe “Estudante”
que também é “Gravável” e consequentemente poderá ser
persistida usando o “MotorPersistencia”. Agora crie uma
aplicação que permite manipular as notas de estudantes da
turma de Programação Avançada em Java. A aplicação em
causa deverá fornecer [por meio de um menu repetitivo] as
seguintes funcionalidades:
• Criação do estudante (sem incluir as notas) e
armazenamento dos dados deste no ficheiro;
• Atualização [no ficheiro] da nota do teste 1 de um
estudante específico;
• Atualização [no ficheiro] da nota do teste 2 de um
estudante específico;
• Atualização [no ficheiro] da nota do trabalho de um
estudante específico;
• Visualização da situação de um estudante específico;
• Impressão da pauta da turma;

Todos os dados necessários devem ser indicados pelo


utilizador e a persistência de dados deverá ser feita num
ficheiro de nome “pauta_pooa.txt”

94
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Respostas
1. O polimorfismo é a capacidade de um mesmo objeto poder ser
referenciada de múltiplas formas, já a abstração é uma técnica
de programação que procura criar independência entre os
objetos na medida em que é possível conceber uma solução sem
se preocupar com características específicas de um objeto. Ora
a abstração usa do polimorfismo para garantir a desamarração
entre objetos.
2. O uso do polimorfismo e abstração permite conceber soluções
capazes de resolver problemas do futuro.
3. O uso de classes abstratas garante que determinadas classes
não possam ser instanciadas ou mesmo tempo que permite a
inclusão de métodos abstratos; esta última característica é
benéfica para a abstração.
4. A classe estudante

95
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 59: A classe estudante

96
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 60: A classe Estudante – Continuação


5. Resolução

97
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 61: Esqueleto do Programa

98
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 62: O método menu

Figura 63: O método find

99
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 64: O método printPauta

Figura 65: O método atualizaNota

100
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 66: O método visualiza

Figura 67: O método createEstudante

101
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 68: O método printErr

Execícios para avaliação


Nos números seguintes escolha a alternativa mais correta.
1. Que conceito aplicarias para resolver um problema relacionado
com a repetição de código em programa?
a) Abstração;
b) Modularização;
c) Instanciação;
2. Qual é o princípio básico sobre o qual a abstração assenta?
a) Independência entre os objetos;
b) Consistência de dados;
c) Segurança de dados.
3. Herança múltipla ocorre quando uma classe estende mais de
uma superclasse;
a) Em java é possível ter herança múltipla, visto que uma
classe pode “estender” várias superclasses ao mesmo
tempo;
b) Em java não é possível ter herança múltipla. Mas é
possível um determinado objeto ser referenciado de
múltiplas formas por meio de interfaces visto que é
possível uma classe de objectos implementar várias
interfaces;
c) O conceito “Herança múltipla” está além do âmbito de
programação avançada em java.
4. Considere a classe abstrata “AbstractCollection” que
implementa a interface “Collection”. Se a interface “Collection”
assina o método “public boolean isEmpty();” então:
a) A seguinte instrução está errada: “Collection colecao =
new AbstractCollection();”

102
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

b) A seguinte instrução está correcta: “Collection colecao =


new AbstractCollection();”
c) Se “colecao” é uma referência a um objeto do tipo
“Collection”, a instrução seguinte não está correcta:
“boolean result = colecao.isEmpty();”
5. Qual destes se aproxima à herança?
a) Agrupamento de código;
b) Reutilização de código;
c) Beleza de código.
6. O que é herança implícita?
a) É aquela que existe entre as classes nativas do java e a
classe Object;
b) É aquela que existe entre toda e qualquer classe com a
classe Object;
c) Não existe herança implícita, toda herança deve ser
explícita com o uso da palavra reservada “extends”.
7. Em POO o que são métodos modificadores de acesso?
a) São “getters” e “setters”;
b) São métodos especiais que permitem acesso aos
atributos do objeto, quer para leitura quer para a edição
destes.
c) Qualquer método que modifica ou dá acesso ao atributo
da classe.
8. Considere que a classe “Droid” implementa a interface
“Programmable” e que “d” é uma referência a “Droid”. Se a
instrução “d.doSelfDriving ();” está correta, então está
garantido que:
a) A classe “Droid” não é abstrata;
b) A interface “Programmable” assina o método
“doSelfDriving”;
c) As duas opções anteriores são verdadeiras.
9. Qual das seguintes declarações faz referência à abstração?
a) Tratar aspetos complexos do problema, deixar aspetos
simples para serem tratados a posterior;
b) Ir até ao detalhe, tratar um problema genérico ao
pormenor.

103
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

c) Ignorar detalhes, tratar “coisas” diferentes como se


fossem iguais;
10. Considere que a classe “Funcionário” é subclasse da classe
“Pessoa” e esta última não define nenhum construtor.
Considere ainda que a classe “Funcionário” implementa a
interface “Printable”. A instrução “Printable p = new Pessoa ();”
a) Está errada pois tem incompatibilidade de dados;
b) Está errada pois a classe “Pessoa” não tem construtor;
c) Está correta e usa o conceito de polimorfismo;
11. Se a classe “Iphone” é filha da classe “Phone” então a classe
“Iphone” herda todos os atributos e métodos da classe “Phone”
a) Sim, e tem acesso direto a todos eles;
b) Não, pois os métodos “static” não são herdados;
c) Sim, mas nada garante.
12. Considere que a classe “Funcionário” é filha da classe “Pessoa”.
A instrução “Funcionário f = new Coordenador ();” estaria
correta
a) se a classe “Coordenador” fosse filha da classe “Pessoa”;
b) se a classe “Coordenador” fosse filha da classe
“Funcionário”;
c) se a classe “Funcionário” e a classe “Coordenador”
implementassem uma mesma interface;

Respostas: 1b, 2b, 3b, 4a, 5a, 6b, 7b, 8b, 9c, 10a, 11c, 12b

Referências Bibliográficas

Caelum. Java e Orientação a Objetos. Consultado em abril de 2021. Disponível em


https://www.caelum.com.br/apostila-java-orientacao-objetos
Oracle. Object-Oriented Programming Concepts; Consultado em abril de 2021.
Disponível em
https://docs.oracle.com/javase/tutorial/java/concepts/index.html

104
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

TEMA – III: Persistência de Dados com Streams

Unidade temática 3.1. Introdução a “streams”


Unidade temática 3.2. Filereader e filewriter
Unidade temática 3.3. Bufferedreader e bufferedwriter
Unidade temática 3.4. Fileinpustream e fileoutputstream
Unidade temática 3.5. Objectinputstream e objectoutputstream
Unidade temática 3.6. Entrada de dados usando scanner
Unidade temática 3.7. Exercícios deste tema

Unidade temática 3.1: Introdução a “Streams” e


persistência de dados

Introdução
No mundo real, as aplicações interagem com o usuário através de
apresentação de mensagens bem como receção de respostas ou
entradas feitas pelo utilizador. Além disso, as aplicações precisam
persistir dados para futuras consultas bem como recuperar dados
persistidos para novos processamentos. Persistência de dados consiste
em armazenar dados de forma permanente em disco em oposição ao
armazenamento temporário em memoria. Os dados armazenados na
memoria temporária são perdidos quando a aplicação é encerrada daí
a necessidade de persistir os dados de forma permanente. Em java, os
Streams fornecem mecanismos para a persistência e recuperação de
dados em ficheiros. Neste tema serão apresentados diferentes tipos de
Streams e sua utilidade a qual passa desde a entrada de dados usando
dispositivos periféricos, armazenamento de dados em ficheiros planos,
até ao armazenamento de objetos em ficheiros.
Ao completar esta unidade temática 3.1, você deverá ser capaz de:

▪ Explicar: a necessidade de uso de mecanismos de persistência de


dados;
▪ Listar: os diferentes tipos de Streams e sua utilidade.
Objectivos
específicos

Streams disponibilizados pelo JAVA


Conforme referido nas notas introdutórias, as aplicações interagem
com os usuários para a troca de informação. Além disso, as aplicações
persistem os dados para futuro uso dos mesmos. A persistência pode
ser feita de forma mais sofisticada recorrendo às chamadas bases de

105
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

dados, mas também poderá será ser feita em ficheiros usando


diferentes abordagens.
O JAVA disponibiliza inúmeras classes para a manipulação de dados em
ficheiros, as chamadas “Streams”. Dentre os diversos Streams
disponibilizados pelo JAVA podemos destacar os seguintes, os quais
serão abordados com detalhe nas unidades temáticas mais adiante:

• FileInputStream e FileOutputStream: permitem


respetivamente ler e escrever bytes em ficheiro;
• FileReader e FileWriter: permitem respetivamente ler e
escrever carateres em ficheiros de texto;
• BufferedReader e BufferedWriter: fornecem mecanismos
mais eficientes de leitura e escrita de dados em ficheiros de
texto;
• ObjectInputStream e ObjectOutputStream: permitem
respetivamente escrever e ler objeto em ficheiro binários;
• BufferedInputStream e BufferedOutputStream: fornecem
mecanismos mais eficientes de leitura e escrita em ficheiros
binários.

Sumário
Nesta unidade temática 3.1 introduzimos a persistência de dados e
listamos alguns Streams disponibilizados pelo JAVA para a manipulação
de ficheiros, nomeadamente FileInputStream e FileOutputStream,
FileReader e FileWriter, BufferedReader e BufferedWriter,
ObjectInputStream e ObjectOutputStream e ObjectInputStream e
ObjectOutputStream.

106
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Exercícios de autoavaliação
Perguntas
1. O que entendes por persistência de dados?
2. O que são “Streams” do java?
3. Liste alguns “Streams” disponibilizados pelo java.
4. Qual é o propósito dos Streams do tipo “File Stream”?
5. Quais são os Streams indicados para a persistência de dados
em ficheiros de texto?
Respostas:
1. Persistência de dados é o mecanismo pelo qual as aplicações
armazenam de forma permanente os dados captados e ou
processados para posterior uso.
2. Streams são classes que permitem a transferência de dados
entre diferentes dispositivos.
3. Streams disponibilizados pelo java:
a) FileInputStream e FileOutputStream;
b) FileReader e FileWriter;
c) BufferedReader e BufferedWriter;
d) ObjectInputStream e ObjectOutputStream
e) BufferedInputStream e BufferedOutputStream
4. Os Streams do tipo “File Stream” servem para persistir dados
em ficheiros binários.
5. Os Streams responsáveis pela persistência em ficheiros de
texto são FileReader e FileWriter.

Exercícios para avaliação


Marque com V as afirmações verdadeiras e F as falsas:
1. FileInputStream permite a entrada de dados em ficheiro e
FileOutputStream permite a leitura de dados;
2. FileInputStream permite a leitura de dados em ficheiro e
FileOutputStream permite a escrita de dados;
3. FileReader e FileWriter permitem manipular ficheiros de
texto (conjunto de caracteres);
4. FileInputStream recupera dados no formato binário;
5. BufferedReader e FileReader permitem ler ficheiros do
mesmo tipo;
6. Os Streams do tipo “Buffered” são mais eficientes que os dos
outros tipos;
7. ObjectOutputStream e ObjectInputStream permitem
persistir e recuperar objetos em ficheiros;

107
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

8. É possível manipular ficheiros do tipo texto usando


FileInputStream e FileOutputStream;
9. É possível manipular ficheiros binários usando FileReader e
FileWriter;
10. Persistência de dados tem que ver com os dados
armazenados em memória temporária.
Respostas: 1-F, 2-V, 3-V, 4-V, 5-V, 6-V, 7-V, 8-V, 9-F, 10-F.

Unidade temática 3.2: FileReader e Filewriter

Introdução

As classes FileReader e FileWriter permitem escrever e ler carateres em


ficheiros de texto, isto é, ficheiro legíveis para o ser humano em
oposição a ficheiros binários que não são legíveis (por exemplo:
ficheiros contendo imagem, vídeo, pdf, etc.). Nesta unidade temática
3.2 vamos estudar a essência destas classes na manipulação de ficheiros
de texto, quer para a leitura quer para a escrita.
Ao completar esta unidade temática 3.2, você deverá ser capaz de:

▪ Abrir: um ficheiro para a leitura usando FileReader;


▪ Abrir: um ficheiro para a escrita usando FileWriter;
▪ Percorrer: um ficheiro de texto da ponta-a-ponta e recuperar os
Objectivos dados nele contidos;
específicos ▪ Escrever: em um ficheiro de texto;

Abrindo um ficheiro de texto para a escrita usando FileWriter


Para escrever dados num ficheiro de texto o primeiro passo é abrir tal
ficheiro com recurso a um dos construtores da classe FileWriter. A
classe FileWriter disponibiliza (na versão JAVA 6) 5 construtores dos
quais iremos abordar os que são apresentados na figura seguinte.

108
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 69: Construtores da classe FileWriter

No ponto 1 abrimos o ficheiro usando o construtor de 1 parâmetro;


trata-se de uma String que representa o nome do ficheiro ou o caminho
completo (path) para o ficheiro. Caso se use apenas o nome, então
assume-se que o ficheiro está no diretório corrente. Note que nesta
instrução associamos a instância de FileWriter a variável “nomes” a qual
seria usada para manipular o ficheiro. Note que, a abertura do ficheiro
usando este construtor irá causar a sobrecarga do ficheiro com o
mesmo nome, caso exista, o ficheiro será recriado.

No ponto 2 abrimos o ficheiro usando o construtor com dois


parâmetros, nomeadamente, uma String [representando o nome ou o
caminho completo para o ficheiro] e um boolean. Este Segundo
parâmetro indica se o ficheiro deverá ser sobrescritos ou não. O valor
“true” indica que caso o ficheiro exista deverão ser preservados os
dados nele contidos e os novos serão anexados (appended) aos
existentes.

No ponto 4 abrimos o ficheiro recorrendo ao construtor que recebe


instância de “File”. Uma instância de File é uma representação abstrata
de ficheiro ou diretório. O File representa uma estrutura hierárquica de
ficheiros independente do sistema operativo.

A abertura do ficheiro recorrendo ao construtor no ponto 5, tem o


mesmo efeito com o que foi abordado no ponto 2.

109
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Escrevendo em um ficheiro de texto


A escrita de dados num ficheiro de texto é feita recorrendo a métodos
disponibilizados pela classe FileWriter. Basicamente a escrita de dados
é feita usando o método “write”. A figura abaixo apresenta um trecho
de código no qual se escreve num ficheiro de texto usando FileWriter.

Figura 70: Escrita de dados em ficheiro usando FileWriter

Neste trecho de código, inicialmente abre-se um ficheiro recorrendo ao


FileWriter, associa-se este FileWriter à variável “writer”. De seguida
descarrega-se neste ficheiro uma cadeia de caracteres contida na
variável “chars” (ponto 1). Aqui recorreu-se ao método “write” que
recebe como parâmetro um array de “char”. No ponto 2 identifica-se o
separador de linhas do Sistema recorrendo ao método “getProperty”5.
De seguida, no ponto 3, escreve-se no ficheiro o separador de linhas que
irá causar a mudança de linha no ficheiro. No ponto 4, descarrega-se no
ficheiro uma String recorrendo ao método “write” que recebe pelo
parâmetro uma String. Finalmente, no ponto 5, fecha-se o ficheiro
recorrendo ao método “close”. É importante que após encerrar as
operações sobre o ficheiro o mesmo seja fechado para confirmar a
escrita de dados e liberar o ficheiro para uso por outros aplicativos. Note
que, antes de fechar o ficheiro, qualquer alteração nele efetuada não se
efetivará e que depois de fechar o ficheiro o mesmo não poderá ser
manipulado, a não ser que seja novamente aberto.

5
Cada Sistema operativo possui uma codificação específica para separar linhas. Por
exemplo, o Sistema operative Windows usa a codificação ‘\r\n’ para separar linhas, o
linux usa ‘\n’. O uso da propriedade “line.separator” garante que o código será
independente do Sistema operative uma vez que nao se amarra a uma codificação
específica.

110
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Abertura de ficheiro de texto para a leitura usando FileReader


A leitura de ficheiros de texto usando o FileReader passa pela criação
de instância de FileReader o qual fica sempre associado a um ficheiro.
Trata-se da abertura do ficheiro para leitura. Após a abertura do ficheiro
passa-se a leitura do mesmo usando o método “read” disponibilizado
pela classe FileReader. No trecho de código apresentado na figura
seguinte apresenta-se a essência do processo de leitura de dados em
um ficheiro de texto.

Neste trecho de código inicialmente abre-se o ficheiro “nomes.txt”


recorrendo ao construtor de FileReader que recebe uma String, esta string
representa o nome do ficheiro ou o caminho completo para o ficheiro.
Note que associamos este ficheiro a variável “reader” esta será a variável
a ser usada para aceder ao ficheiro.
No ponto 2, abrimos o mesmo ficheiro recorrendo ao construtor que
recebe instância de “File”.
A leitura de dados do ficheiro é feita recorrendo ao método “read”. Este
método lé o carater corrente do ficheiro e avança o curso para o próximo
carater. Note que este método lê o ficheiro no formato byte. No nosso
exemplo, a leitura do primeiro carater é feita no ponto 3.
Finalmente, no ponto fechamos o ficheiro recorrendo ao método “close”.

Recuperando os dados do ficheiro da ponta-a-ponta


A leitura completa de ficheiro usando FileReader é feita com recurso ao
uso de ciclos. O ciclo mais indicado para este efeito é o ciclo “while”. No
código apresentado na figura seguinte faz-se a recuperação de todos os
caracteres contidos num ficheiro.
Neste exemplo, vamos supor que estamos a
recuperar o conteúdo do ficheiro “somas.txt”
disposto como na imagem a direita.

111
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 71: Abertura e recuperação de dados em um ficheiro


Neste exemplo abriu-se o ficheiro “somas.txt” para a leitura recorrendo
ao FileReader. Note que associamos uma instância desta classe a variável
“reader”. No ponto 2, faz-se a leitura do primeiro caracter no ficheiro
usando o método “read”. Note o uso do ciclo “while” para varrer o
ficheiro da ponta-a-ponta. O método “read” lê o carater corrente e avança
o curso para o próximo carater. A cada iteração lê-se o caracter corrente
recorrendo ao método “read” (ponto 4). Quando o cursor atingir o fim do
ficheiro, o método “read” irá retornar “-1” indicando que já não há
carateres por ler; é por isso que usamos a “c != -1” como condição de
execução do nosso ciclo “while”.
A cada iteração do ciclo “while” imprime-se cada caracter recuperado
(ponto 3). Note que o output será em bytes, pois o método “read” lê os
caracteres no formato byte. Mais abaixo ilustra-se a conversão dos bytes
em caracteres simplesmente através do casting do “int” para “char”
(linha 5). Note que, aqui o output coincide com o conteúdo do ficheiro
“somas.txt”.
112
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Sumário
Nesta unidade temática 3.2 apresentamos os mecanismos de
manipulação de ficheiros de texto usando FileWriter e FileReader.
Trata-se de classes que permitem escrever e ler de ficheiros de texto.

113
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Exercícios de autoavaliação
Perguntas
1. Para que tipo de ficheiros se indica o uso de FileReader e
FileWriter?
2. Descreva o processo de escrita de dados no ficheiro usando
FileWriter;
3. Descreva o processo de leitura de dados contidos no ficheiro
usando FileReader.
4. Qual é a importância do uso do método “close” sobre um
FileWriter?
5. Crie um programa que permite escrever 5 linhas em um
ficheiro de texto. Cada linha deverá conter a operação de
soma de 2 números a sua escolha.
6. Cria um programa que permite recuperar e visualizar o
conteúdo do ficheiro criado no exercício anterior.
Respostas
1. FileReader e FileWriter são indicados para ficheiros do tipo
texto, isto é, ficheiros legíveis para o ser humano.
2. Para escrever dados em ficheiro usando FileWriter, primeiro
instancia-se a classe FileWriter usando um dos seus
construtores; o construtor obriga sempre a indicação do
ficheiro em que se pretender escrever dados; de seguida,
usa-se o método “write” para escrever os dadospretendidos;
no final, invoca-se o método “close” sobre a instância de
FileWriter para fechar o ficheiro.
3. Para ler dados em ficheiro de texto usando a classe
“FileReader”, primeiro instancia-se a classe FileReader
usando um dos construtores desta classe; o construtor exige
sempre a indicação do ficheiro que se pretende ler; de
seguida faz se a leitura do dado corrente usando o método
“read”.
4. O método “close” permite fechar o ficheiro e liberá-lo para
uso por outras aplicações.
5. Resolução

114
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 72: Resolução exercício 5

6. Resolução

Figura 73: Resolução exercício 6

Exercícios para avaliação


Nos números seguintes escolha a afirmação mais correta.
115
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

1. Para a recuperação de dados em ficheiro de texto usamos


a) A classe FileReader;
b) Instância de FileReader;
c) O método “read” invocado sobre instância de
FileReader;
2. Como se faz a mudança de linha quando se usa FileWriter
para escrever em ficheiro
a) Invocando o método “newLine()” sobre instância de
FileWriter;
b) Invocando o método “write” sobre instância de
FileWriter
c) Passando o código de separação de linhas ao método
“write” de FileWriter;
3. Qual é a melhor forma de “varrer” um ficheiro de texto da
ponta-a-ponta?
a) Usando um ciclo “do-while” aliado ao método “read” de
FileWriter
b) Usando um ciclo “while”;
c) Usando um ciclo “do-while” aliado ao método “read” de
FileWriter
4. Quando se trabalha sobre um ficheiro usando FileWriter é
importante que no final se feche o mesmo, pois:
a) Garante que os dados serão persistidos;
b) Garante que as alterações nele efetuadas serão salvas e
o ficheiro será liberado.
c) Garante que o ficheiro seja liberado para uso por outros
programas ou rotinas.
5. A criação de um ficheiro usando FileWriter pode é feita
recorrendo:
a) Ao método construtor;
b) Ao um método de instância definido nesta classe;
c) Recorrendo a classe File.
6. Qual é o risco que se corre ao instanciar um ficheiro usando
o construtor de um parâmetro da classe FileWriter?
a) Corre-se o risco de danificar o disco duro;
b) Corre-se risco de danificar possível ficheiro já existente;

116
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

c) Corre-se risco de ter uma exceção que poderá causar


paragem do programa.
7. O que acontece ao tentar escrever num ficheiro depois de
invocar o método “close” sobre a referência associada a tal
ficheiro?
d) Nada de mais, a escrita irá ocorrer normalmente;
a) O ficheiro será reaberto, e a escrita será feita;
b) A escrita não irá ocorrer e um erro será reportado.
8. O que faz o método “read” da classe “FileReader”?
a) Lê a linha corrente do ficheiro e avança o cursor para a
próxima linha;
b) Lê a palavra corrente do ficheiro e avança o cursor para
a próxima palavra;
c) Lê o carater corrente e avança o cursor para o próximo
carater.
9. Verdade ou falso que o método “read” da classe FileReader
retorna o carater corrente?
a) Verdade;
b) Falso;
c) Pode ser verdade, mas por vezes falso;
10. Qual é o retorno do método “read” da classe FileReader?
a) Inteiro correspondente ao carater corrente;
b) Carater corrente;
c) Byte corrente.

Respostas: 1-c, 2-c, 3-b, 4-c, 5-a, 6-b, 7-c, 8-c, 9-b, 10-a.

Unidade temática 3.3 BufferedWriter e BufferedReader

Introdução
À semelhança das classes FileReader e FileWriter, as classes
BufferedWriter e BufferedReader permitem escrever e ler em ficheiros
de texto, no entanto estas classes permitem trabalhar com cadeias de
caracteres ao invés de carateres simples. Além disso estas classes fazem
parte de um grupo de Streams chamados “buferizados” (buffered) os
quais fornecem mecanismos mais eficientes de acesso aos ficheiros.
Nesta unidade temática 3.3 vamos estudar a essência destas classes na

117
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

manipulação de ficheiros de texto, quer para a leitura quer para a


escrita.
Ao completar esta unidade temática 3.3, você deverá ser capaz de:

▪ Explicar: a diferença entre Streams não “buferizados” e Streams


“buferizados”;
▪ Abrir: um ficheiro para a leitura usando BufferedReader;
Objectivos
▪ Abrir: um ficheiro para a escrita usando BufferedWriter.
específicos
▪ Percorrer: um ficheiro de texto da ponta-a-ponta e recuperar os
dados nele contidos usando BufferedReader;
▪ Processar: dados recuperados de um ficheiro de texto disposto
em um formato específico;
▪ Escrever: em um ficheiro de texto;
▪ Atualizar: dados contidos em ficheiro de texto.

Streams “buferizados” (buffered)


Para melhor entender o que são Streams buferizados primeiro é
necessário perceber como funcionam os Streams não “buferizados”. Em
Streams não “buferizados”, cada operação de leitura ou escrita em
ficheiro é tratada a nível do sistema operativo, isto é, a nível do disco.
Os Streams “buferizados” trabalham a nível da memória em uma área
conhecida como “buffer”, trata-se de uma área intermédia entre a
aplicação e o disco. Nesta abordagem o acesso ao disco físico só é feito
quando requerido, normalmente quando o “buffer” estiver vazio (no
caso de leitura de dados) ou quando “buffer” estiver cheio (no caso de
escrita de dados). Esta abordagem melhora a eficiência das aplicações
visto que limita o acesso ao disco quando necessário trabalhando a nível
de memória na maioria das vezes. É por essa razão que é mais
recomendado o uso de Streams “buferizados” em detrimento dos não
“buferizados”.

Abrindo um ficheiro de texto para a escrita usando BufferedWriter


BufferedWriter é um “wrapper” (embrulho) do FileWriter (ou qualquer
outro Writer não “buferizado”). Isto significa que esta classe
transforma um Writer não “buferizado” em “buferizado”. A escrita de
dados usando BufferedWriter exigirá sempre a presença de um
FileWriter. No exemplo apresentado na figura seguinte apresenta-se a
essência de escrita de dados usando um BufferedWriter associado a
um FileWriter.

118
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 74: Processo de escrita de dados em ficheiro usando BufferedWriter

O código apresentando na figura anterior permite escrever dois nomes


num ficheiro de texto (“nomes.txt”). Note que para instanciar um
BufferedWriter precisamos de ter um FileWriter. No ponto 1, cria-se a
instância de um BufferedWriter usando o construtor que recebe um
FileWriter como parâmetro. No ponto 2, escreve-se no buffer o
primeiro nome. No ponto 3, avança-se o cursor para a linha seguinte.
Note que tudo o que se escreve no buffer só será refletido com a
chamada ao método “flush” ou quando o ficheiro for encerrado. No
nosso exemplo invocamos o “flush” no ponto 4. A chamada a este
método deve ser feita sempre em pontos cruciais da aplicação para
evitar inconsistência de dados. Por exemplo quando estamos a
trabalhar com uma transação composta por várias operações, o flush
deverá ser invocado quando todas as operações da transação
estiverem completas.

Leitura de dados em ficheiro de texto usando BufferedReader


À semelhança do BufferedWriter, a classe BufferedReader é um
“wrapper” do FileReader (ou qualquer outro Reader). Um
BufferedReader estará sempre associado a um Reader. A classe
BufferedReader fornece o método “readLine” que permite ler do
ficheiro a linha corrente flexibilizando desta forma o processo de leitura
de dados em ficheiro de texto.

119
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

A figura seguinte ilustra um exemplo do processo de recuperação de


dados num ficheiro usando um BufferedReader.

Figura 75: Abertura e recuperação de dados em ficheiro usando BufferedReader


No código apresentando na figura anterior ilustra-se a essência de
recuperação de dados de um ficheiro usando BufferedReader. Neste
código abre-se um ficheiro designado “nomes.txt” e recupera-se todas as
linhas nele contido e imprime-se na tela. No ponto 1, instancia-se
BufferedReader e associa-se a variável “b”. Note que aqui usou-se o
construtor que recebe pelo parâmetro um FileReader.
De seguida percorre-se o ficheiro por meio de um ciclo “while”. Note a
invocação do método “ready” como condição do ciclo (no ponto 2). Este
método retorna “true” se a linha corrente do ficheiro não estiver vazia ou
se não tiver sido alcançado o fim do ficheiro.
A cada iteração lê-se do ficheiro a linha corrente (ponto 3) e imprime-se
na tela. Note o uso do método “readLine”! Este método recupera a linha
corrente do ficheiro e avança o cursor para a linha seguinte.

Problemas envolvendo ficheiros de texto


Considere o seguinte problema: crie um programa que permite gerar
uma pauta com base em dados armazenados num ficheiro de texto de
nome “notas.txt”. Suponha que o ficheiro em causa tem um número
indefinido de linhas e que os dados estão organizados conforme ilustra
a figura seguinte; onde, a primeira coluna guarda o nome, a segunda
e terceira coluna guardam respetivamente as notas do primeiro e
segundo teste.

120
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 76: Ilustração do ficheiro contendo notas de estudantes


Este é um problema típico envolvendo ficheiros de texto e a sua
resolução passa pela extração dos dados do registo contidos em cada
linha. Existem classes específicas criadas para a extração de dados de
registos apresentados em linhas de ficheiros de texto. No nosso caso
faremos uso do método “split” da classe String que permite transformar
uma linha de texto num array de String com base num caracter de
separação de dados. No nosso exemplo o caracter de separação é o
hífen (-).
A figura seguinte apresenta o código completo que permite abrir o
ficheiro “pauta.txt”, lê as linhas nele contidos e para cada linha recupera
os elementos necessários para a elaboração da pauta, a saber: nome do
estudante, nota 1 e nota 2.

Figura 77: Criação de pauta com base em dados armazenados em ficheiro de texto

121
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Note o uso do método “split” no ponto 1; esta é a chave para a


recuperação de dados! O método “split” da classe String permite
separar os elementos contidos numa string dado o caracter de
separação. No nosso caso, a informação das notas está separada por
hífen e em cada linha temos 3 dados, a saber: o nome do estudante, a
nota do teste 1, a nota do teste 2. O método “split” invocado sobre as
linhas do nosso ficheiro, retorna um array contendo estes 3 elementos
listados. Nos pontos 2, 3 e 4 recuperamos os elementos do array,
começamos pelo nome do estudante, depois recuperamos as notas 1 e
2. Note o uso do método “Double.parseDouble(…)” para as notas dos
testes. O uso deste método se faz necessário pois os dados estão
armazenados em formato string, no entanto nós pretendemos efetuar
operações matemáticas com estas notas.
Uma vez recuperados os dados, no ponto 5 faz-se o processamento dos
mesmos o que consiste em calcular a média das notas e de seguida faz-
se a impressão da pauta no ponto 6.

Atualizando um ficheiro de texto


Embora o JAVA permita incluir novos dados em um ficheiro já existente,
não disponibiliza mecanismos prontos para a atualização de conteúdos
de ficheiros, isto é, modificar partes do conteúdo já existente no
ficheiro. No entanto é possível fazer esta atualização usando alguns
truques. O truque mais comum consiste em copiar o conteúdo do
ficheiro e reescreve-lo em um outro ficheiro substituindo as partes que
se pretende atualizar. Note que para poder substituir o conteúdo é
necessário conhecer o padrão do que se pretende modificar.
No exemplo seguinte vamos alterar as notas de um estudante dado o
seu nome completo. Vamos usar neste exemplo o ficheiro “notas.txt”
usando no exemplo anterior.

122
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 78: Atualização do conteúdo do ficheiro

Note que neste exemplo criamos dois “buffers” um para ler o ficheiro
original e outro para escrever no ficheiro temporário [ponto 2]. O
algoritmo usado para atualizar o ficheiro consiste na leitura do ficheiro
original usando o buffer “reader” e verificar se o estudante na linha
corrente corresponde ao estudante que pretendemos atualizar; caso
seja, modificamos os dados da linha corrente para os novos dados.

Note que, no ponto 3, definimos o estudante que pretendemos


atualizar [Ramussense Thomas]. Aqui fixamos um nome específico, mas
poderíamos ter lido este nome pelo teclado. Igualmente, no ponto 4,
fixamos as novas notas para o estudante; os mesmos poderiam ter sido
solicitados ao usuário.

A seguir, usando o ciclo “while” percorremos o ficheiro e a cada iteração


recuperamos os dados da linha corrente do ficheiro. Neste caso
interessa nos apenas o nome pois é com ele que iremos verificar se a
linha corrente corresponde ao estudante pretendido. Note o uso do
método “trim ()” sobre o nome, no ponto 5! Este método permite
remover espaços em branco em uma
123
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

String. Isto é necessário porque um texto recuperado do ficheiro poderá


ter espaços em branco no final.
No ponto 6, verificamos se o nome do estudante na linha corrente do
ficheiro coincide com o nome do estudante que pretendemos atualizar
e caso seja modificamos os seus dados.
Finalmente, no ponto 7, escrevemos os dados no ficheiro temporário
recorrendo ao buffer “writer”. Note que a variável “linha” irá conter o
mesmo conteúdo da linha corrente se o estudante nesta linha não for o
estudante que se pretende modificar.
No ponto 8, primeiro removemos o ficheiro original e depois
renomeamos o ficheiro temporário para o nome do ficheiro original.
Desta forma conseguimos atualizar o ficheiro!

Sumário
Nesta unidade temática 3.3 apresentamos os mecanismos de
manipulação de ficheiros de texto usando BufferedReader e
BufferedWriter. Começamos por explicar a particularidade de Streams
“buferizado”. Fomos ao fundo apresentando mecanismos de resolução
de problemas envolvendo ficheiros de texto. E finalmente
apresentamos um algoritmo para a atualização de ficheiros de texto
usando estas duas classes, a classe BufferedReader e BufferedWriter.

Exercícios de autoavaliação
Perguntas
1. Explique a diferença entre Streams “buferizados” e Streams
não “buferizados”.
2. Quais são as vantagens do BufferedReader sobre o
FileReader?
3. Descreva um algoritmo para a atualização de um ficheiro de
texto recorrendo ao BufferedReader e BufferedWriter;
4. Para que server o método “split” da classe String e como ele
é útil no manejo de dados de ficheiros de texto?
5. Quando se deve usar o método “flush” do BufferedWriter?
6. Crie um programa que lê, pelo teclado, uma lista de nomes
de estudantes e armazena-os num ficheiro de tipo texto.

NOTA • Os nomes devem ser armazenados em forma


de lista, isto é, um em baixo do outro.

• O tamanho da lista é indefinido.

124
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

7. Elabore um programa que permite gerar uma pauta de


estudantes e armazená-la num ficheiro de texto. O ficheiro
gerado deverá ter a seguinte aparência:

NOTA: 1. A quantidade de estudantes é indefinida.

2. Para cada estudante o programa deverá obter as


notas nos dois testes e de seguida achar a média.
3. O programa deverá usar conceitos de orientação a
objectos, e os dados devem ser inicialmente
armazenados num array de Estudantes e no fim os
dados no array deverá ser descarregado no ficheiro.

8. Os dados necessários para processar o salário de uma


determinada instituição encontram-se armazenados num
ficheiro de texto. Recorrendo a orientação a objetos, elabore
um programa que recupera os dados, processa o salário de
todos os trabalhadores e, escreve num ficheiro a folha de
salários da instituição. (NOTA: suponha que os dados
estejam armazenados conforme ilustra a figura baixo).

Notas: Suponha que a fórmula para o cálculo do salário seja


a seguinte:
horasTrabalhadas * salarioDiario /8 - (horasAtraso *
salarioDiario/8)*0.75;

125
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Respostas:
1. Usando Streams não “buferizados”, cada operação de leitura
ou escrita em ficheiro é tratada a nível do sistema operativo,
isto é, a nível do disco. Os Streams “buferizados” trabalham
a nível da memória em uma área conhecida como “buffer”,
trata-se de uma área intermédia entre a aplicação e o disco.
Nesta abordagem o acesso ao disco físico só é feito quando
requerido, normalmente quando o “buffer” estiver vazio (no
caso de leitura de dados) ou quando “buffer” estiver cheio
(no caso de escrita de dados).
2. O BufferedReader oferece mecanismos mais flexíveis de
leitura de ficheiro de texto uma vez que permite leitura de
linhas, além disso, a leitura de ficheiro usando
BufferedReader é relativamente mais rápida.
3. O algoritmo usado para atualizar o ficheiro consiste na
leitura iterativa do ficheiro original usando BufferedReader
da primeira linha até a última linha escrevendo o conteúdo
do ficheiro original num ficheiro temporário. A cada
interação verifica-se o registo na linha corrente corresponde
ao registo que pretendemos atualizar. Caso seja, modifica-
se os dados da linha corrente para os novos dados antes de
escrever a linha corrente no ficheiro temporário. No final,
remove-se o ficheiro original e renomeia-se o ficheiro
temporário para o nome do ficheiro original.
4. O método “split” permite dividir uma string em partes dado
o caracter (ou caracteres de separação). Este método é
bastante útil no processo de recuperação de dados
armazenados em ficheiro de texto em que os registos ficam
armazenados em linha visto que permite a decifração dos
dados do registo.
5. O método “flush” deve ser usado para confirmar a
persistência dos dados correntes no ficheiro.
6. Resolução

126
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 79: Resolução exercício 6

7. Resolução

A solução deste exercício é composta por duas classes, a classe


Estudante que representa a entidade do modelo de dados (mais a
baixo) e a classe App03_03_07, que representa a aplicação.

127
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 80: Aplicação com ficheiros para o exercício 7

128
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 81: Entidade Estudante para o execício 7


8. Resolução
A solução deste exercício é composta por duas classes, a classe
Trabalhador que representa a entidade do modelo de dados (mais a
baixo) e a classe App03_03_08, que representa a aplicação.

129
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 82: Aplicação com ficheiros para o exercício 8

Figura 83: Entidade Trabalhador para o exercício 8

130
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Exercícios para avaliação


Nos números seguintes escolha a afirmação mais correta
1. Para que serve o método “flush” do BufferedWriter?
a) Fechar o ficheiro e confirmar a gravação de dados;
b) Confirmar a gravação de dados no ficheiro e liberar o
ficheiro;
c) Confirma a gravação [no ficheiro] dos dados contidos no
buffer;
2. Como se faz a mudança de linha quando se usa
BufferedWriter para escrever em ficheiro?
a) Invocando o método “newLine()” sobre instância de
BufferedWriter;
b) Invocando o método “newLine()” sobre a classe
BufferedWriter
c) Passando o código de separação de linhas ao método
“write” de BufferedWriter;
3. Qual das seguintes afirmações é mais correta?
a) Em JAVA não é possível atualizar o conteúdo de um
ficheiro de texto;
b) O método “split” da classe String é indicado para resolver
problemas relacionados com ficheiros de texto;
c) O algoritmo para atualizar um ficheiro de texto consiste
na “varredura” do ficheiro e substituição das linhas que
se pretende substituir.
4. Qual é a relação existente entre FileWriter eBufferedWriter?
a) BufferedWriter é subclasse de FileWriter;
b) BufferedWriter tem FileWriter como um dos elementos
e usa-o para a efetivação da escrita no ficheiro;
c) FileWriter é um “wrapper” de BufferedWriter.
5. Qual destas afirmações expõe melhor a diferença entre
FileReader e BufferedReader?
a) FileReader faz parte dos elementos de BufferedReader;
b) FileReader faz menos consulta ao dispositivo de
armazenamento que o BufferedReader;
c) BufferedReader executa menos operações no
dispositivo de armazenamento.
6. Quais são as vantagens de BufferedReader sobre
FileReader?

131
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

a) BufferedReader disponibiliza métodos mais intuitivos de


acesso aos dados;
b) BufferedReader pode ser mais rápido;
c) As duas opções anteriores são corretas.
7. Qual das seguintes afirmações é verdadeira?
a) Em um Stream [para a escrita de dados] do tipo buffer a
não invocação do método “flush” causará a perda de
todos os dados escritos no ficheiro;
b) Em um Stream [para a escrita de dados] do tipo buffer a
não invocação do método “close” causará a perda de
todos os dados escritos no ficheiro;
c) O método “flush” ou “close” fazem com que os dados
sejam persistidos no ficheiro quando se usa um Stream
[para a escrita de dados] do tipo buffer.
8. Qual é a função do método “readLine” de um
BufferedReader?
a) Disponibiliza o conteúdo da linha corrente do ficheiro
associado ao buffer e avança o cursor para a próxima
linha;
b) Lê a palavra corrente do ficheiro e avança o cursor para
a próxima;
c) Lê a linha corrente do ficheiro associado ao buffer.
9. Qual das seguintes afirmações não pode ser verdadeira?
a) O método “readLine” de um BufferedReader retorna
sempre uma string;
b) O método “ready” de um BufferedReader retorna
sempre o boolean;
c) As duas afirmações anteriores são verdadeiras.
10. Qual é a diferença fundamental entre BufferedWriter e
FileWriter?
a) Tem que ver com o momento em que os dados são
escritos no disco;
b) Tem que ver com a forma como os dados são escritos no
disco;
c) Tem que ver com a resolução em que os dados são
escritos no disco.

Respostas: 1c, 2a, 3b, 4b, 5c, 6c, 7c, 8a, 9b, 10a

132
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Unidade temática 3.4: FileInputStream e


FileOutputStream

Introdução

As classes FileOutputStream e FileInputStream permitem escrever e ler


em ficheiros no formato binários. Normalmente, estas classes são
indicadas para manipular ficheiros binários, isto é, ficheiro não legíveis
para o ser humano tais como: ficheiros contendo imagem, vídeo, pdf,
etc.). Nesta unidade temática 3.4 vamos estudar a essência destas
classes na manipulação de ficheiros, quer para a leitura quer para a
escrita.
Ao completar esta unidade temática 3.4, você deverá ser capaz de:

▪ Explicar: a necessidade do uso das classes FileOutputStream e


FileInputStream;
▪ Abrir: um ficheiro para a leitura usando FileInputStream;
Objectivos ▪ Abrir: um ficheiro para a escrita usando FileOutputStream.
específicos ▪ Transferir: dados binários de ficheiro para outro;

Porquê FileOutputStream e FileInputStream


As classes FileOutputStream e FileInputStream fazem parte dos Streams
conhecidos como “Byte Streams” que permitem manipular dados no
formato binários. Dados binários, são dados normalmente ilegíveis para
o ser humano, tais como, dados em ficheiros de áudio, vídeo, imagem e
outros tipos. Normalmente o conteúdo de ficheiros binários é
interpretado por meio de aplicativos específicos com suporte a
formatos específicos de dados, tais como: leitores de áudio, leitores de
vídeo, leitores de PDF, etc. Uma vez que os ficheiros binários, na sua
maioria são ilegíveis para o ser humano, as classes FileOutputStream e
FileInputStream são usadas no processo de transferência de dados
entre ficheiros ou entre aplicativos. Nesta unidade temática iremos nos
restringir a aplicar estes dois “Streams” para a cópia de dados de um
ficheiro para outro.

Cópia de ficheiro usando FileInputStream e FileOutputStream


Conforme referido anteriormente, FileOutputStream e FileInputStream
são usados para a transferência de dados binários entre aplicativos e
ficheiros. O processo de cópia de ficheiros binários será a essência desta
unidade temática! Este processo começa pela associação do ficheiro aos
Streams, nomeadamente, o FileOutputStream ao ficheiro que se
pretende escrever os dados e o
133
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

FileInputStream ao ficheiro do qual se pretende ler os dados. No


exemplo seguinte ilustra-se o processo de cópia de um ficheiro do tipo
“mp3” de um diretório (do sistema operativo “Windows”) para outro.

Figura 84: Transferência de Dados de Um Ficheiro para Outro

A figura anterior ilustra o processo de transferência de dados de um


ficheiro binário para outro. O programa começa por definir [no ponto
1] o diretório onde os ficheiros estão localizados6. A seguir, no ponto
2, definimos o caminho para os ficheiros (“path”). No ponto 3
associamos os ficheiros aos respetivos Streams.
No ponto 4 lemos o primeiro byte do ficheiro recorrendo ao método
“read”. Este método retorna um “int” que representa o código
numérico do byte [ASCII]. A seguir por meio de um ciclo “while”

6
Note o uso da constante “File.separator”! Esta constante indica o
separador de diretórios do sistema operativo. O uso desta constante é
mais indicado em relação ao uso de separador específico para um sistema
operativo, pois garante maior portabilidade das aplicações uma vez que
o mesmo é dinâmico e fornecerá o separador apropriado para cada
sistema operativo.

134
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

varremos todo o ficheiro. A cada iteração primeiro escrevemos no


ficheiro destino o byte corrente (ponto 6) e de seguida lemos o
próximo byte [linha 7]. O método “read” lê o byte corrente e avança o
cursor para o byte seguinte. Este método irá retornar “-1” se se
alcançar o fim do ficheiro. Daí o uso da condição “c != -1” como
condição para continuar a varredura do ficheiro [ponto 5].
Finalmente no ponto 8, encerramos os nossos ficheiros. É importante
garantir que os ficheiros sejam encerrados para liberar recursos e para
garantir que os dados serão persistidos (no caso de FileOutputStream).
Além do método “read ()” pode se usar o método “read (byte []
buffer)”. Diferentemente do primeiro (que lê apenas um byte), este
método permite ler múltiplos bytes de uma única vez e os transfere
para o “buffer” passado pelo parâmetro. Trata-se de um array de
bytes.

Sumário
Nesta unidade temática 3.4 apresentamos os mecanismos de
manipulação de ficheiros binários usando FileInputStream e
FileOutputStream. Trata-se de classes que permitem a transferência de
dados binários entre ficheiros ou entre aplicativos.

135
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Exercícios de autoavaliação
Perguntas
1. Explique a necessidade do uso de Byte Streams?
2. Dê exemplos de Bytes Streams;
3. Descreva o processo de transferência de dados com
FileInputStream e FileOutputStream.
4. Explique a diferença entre os métodos “read()” e
“read(byte[] buffer)” da classe FileInputStream.
5. Crie um programa que permite transferir os dados de
ficheiro do tipo mp3 para outro. Para a leitura do ficheiro
origem use o método “read (byte [] buffer)”
Respostas
1. Os Byte Stream são usados para a transferência de dados
binários entre aplicativos;
2. FileOutputStream e FileInputStream;
3. O processo de transferência de dados entre ficheiros
começa pela associação dos ficheiros aos Streams,
nomeadamente, o FileOutputStream ao ficheiro que se
pretende escrever os dados e o FileInputStream ao ficheiro
do qual se pretende ler os dados. A seguir por meio de um
ciclo “while” varre-se o ficheiro origem. A cada iteração
primeiro lê-se do ficheiro origem e depois escreve-se no
ficheiro destino o byte corrente e de seguida lê-se o próximo
byte usando o método “read”.
4. O método “read ()” lê e retorna o byte corrente. O método
“read (byte [] buffer)” lê múltiplos bytes de uma única vez e
os transfere para o “buffer” passado pelo parâmetro.
5. Resolução

136
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 85: Transferência de dados usando o InputStreams

Exercícios para avaliação


Nos números seguintes escolha a afirmação mais correta:
1. FileInputStream e FileOutputStream são indicados para
a) Persistência de dados e recuperação dos mesmos em
ficheiros de texto;
b) Persistência de dados e recuperação dos mesmos em
ficheiros binários;
c) Para a transferência de dados binários entre ficheiros e
aplicativos.
2. Qual é a relevância da mudança de linha em um ficheiro
binário?
a) Não tem nenhuma relevância;
b) Garante melhor organização de dados e garante
legibilidade dos dados;
c) Nenhuma opção é correta.
3. Verdade ou falso que a chamada ao método “read” de um
FileInputStream retorna sempre o byte corrente de um
ficheiro binário?
a) Verdade;
b) Falso;
c) Nem falso nem verdade.
4. Quando usamos um FileInputStream para ler dados de um
ficheiro como sabemos que alcançamos o fim do ficheiro?
a) Quando a chamada ao método “ready” retorna “false”;

137
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

b) Quando a chamada ao método “read” retorna um


número negativo;
c) Quando a aplicação rebenta um erro.
5. Em todos os casos, o método “read” da classe
FileInputStream lê o byte corrente e avança o cursor para o
próximo byte.
a) Sim;
b) Não;
c) Talvez.
6. A chamada do método “close” sobre um FileOutputStream
garante
a) Que o ficheiro seja encarrado e liberado;
b) Que o ficheiro seja escrito e liberado;
c) Que o ficheiro seja escrito.
7. Qual é a diferença fundamental entre o método “read()” e
“read(byte[] b)” de um FileInputStream?
a) O primeiro lê um carater a cada chamada e o segundo lê
múltiplos carateres;
b) O primeiro lê um byte a cada chamada e o segundo,
múltiplos bytes;
c) O primeiro lê 1 byte a cada invocação e o segundo lê
1024 bytes.
8. É possível varrer um ficheiro de bytes usando o ciclo “do-
while”?
a) Sim;
b) Não;
c) Talvez.
9. Em um FileOutputStream, qual é a diferença entre o método
“write (int)” e “write (byte [])”?
a) O primeiro escreve no ficheiro um byte e o segundo
escreve múltiplos bytes.
b) O primeiro escreve no ficheiro um “int” e o segundo,
escreve bytes;
c) Ambos têm exatamente a mesma função.
10. Quando se trabalha com hierarquia de diretórios, qual é a
vantagem de usar “File.separator”?
a) Garante independência da plataforma;
b) Garante legibilidade do código;
c) Garante segurança.
Respostas: 1a, 2a, 3b, 4b, 5b, 6b, 7b, 8a, 9a, 10a

138
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Unidade temática 3.5. ObjectInputStream E


ObjectOutputStream

Introdução

As classes ObjectOutputStream e ObjectInputStream permitem


escrever e recuperar um objeto de um ficheiro. O processo de escrita
de objeto em ficheiro é conhecido como serialização. E o processo
inverso é conhecido como de-serialização e consiste na conversão de
bytes contidos no ficheiro em instancia original do objeto. Nesta
unidade temática 3.5 vamos estudar a essência da persistência e
recuperação de objetos de ficheiros.
Ao completar esta unidade temática 3.5, você deverá ser capaz de:

▪ Explicar: o processo de serialização e de-serialização;


▪ Persistir: objetos em ficheiro;
▪ Recuperar: objetos contidos em ficheiro.
Objectivos
específicos

Entendendo o processo de serialização e de-serialização


Um objeto (instância de classe) representa uma coleção de dados
armazenados em memória os quais obedecem a um padrão definido
por um descritor, a classe de objeto. O processo de serialização é o
processo pelo qual o estado corrente de um objeto é transformado em
bytes de modo a permitir a sua transferência usando Streams. A
serialização envolve sempre uma instância e a classe de objetos a que
tal instância pertence. Comumente, a serialização para ficheiros é
conseguida recorrendo a classe ObjectOutputStream. Para que um
objeto possa ser serializado usando a classe ObjectOutputStream, é
necessário que a classe [de objeto] correspondente implemente a
interface “java.io.Serializable”. Além disso, cada atributo desta classe
deverá também ser “Serializable”, isto é, os descritores destes atributos
deverão implementar a mesma interface. Por exemplo, se a classe
Conta define um atributo “titular” do tipo Pessoa, então para que a
conta possa ser serializável, é necessário que a classe Conta e a classe
Pessoa implementem a interface “Serializable”.
O processo de recuperação de instância de uma classe de um ficheiro é
conhecido como de-serialização e consiste na conversão de bytes
[armazenados em disco] em uma instância de classe. Isto é conseguido
recorrendo a classe “ObjectInputStream”. É obrigatório que o descritor

139
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

(classe de objeto) usado no momento da serialização esteja na mesma


versão no momento da recuperação do objeto do ficheiro sob o risco
de enfrentar a exceção “InvalidClassException” no momento da
recuperação do objeto.
O processo de serialização e de-serialização usando as classes
ObjectOutputStream e ObjectInputStream torna o processo de
persistência e recuperação de dados em ficheiro mais simples e
transparente do ponto de vista de código; no entanto desaconselha-se
o seu uso em aplicações de média e grande porte visto que este
processo é bastante lento podendo comprometer a performance do
sistema.

Processo de escrita de objetos em ficheiro


Conforme referido anteriormente, para escrever um objeto num
ficheiro recorremos a classe ObjectOutputStream. A esta classe associa-
se sempre FileOutputStream. O trecho de código seguinte apresenta a
essência do processo de persistência de objeto no ficheiro.

Figura 86: Processo de escrita de objeto no ficheiro

No ponto 1, cria-se uma instância de ObjectOutputStream; note que ele


é associado a um FileOutputStream tratado na unidade temática
anterior. No ponto 2 escrevemos um objeto no ficheiro recorrendo ao
método “writeObject”.

Processo de recuperação de objetos em ficheiro


Para recuperar um objeto de um ficheiro recorremos a classe
ObjectInputStream. À semelhança do ObjectOutputStream, a esta
classe associa-se sempre FileOutputStream que representa o ficheiro do
qual se pretende recuperar o objeto ou objetos. O trecho de código
seguinte apresenta a essência do processo de recuperação de objeto
em ficheiro.

140
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 87: Processo de escrita de objeto no ficheiro

Neste exemplo criou-se uma instância de ObjectInputStream [ponto 1]


associado ao um FileInputStream. De seguida recupera-se deste Stream
um objeto recorrendo ao método “readObject”.

Exemplo
Crie um programa que permite persistir múltiplas instâncias de Pessoa
em um ficheiro de objetos. O programa deverá permitir também
recuperar do ficheiro uma pessoa dado o seu código. Para tal use como
base o descritor de Pessoa apresentado na figura seguinte.

141
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 88: Descritor de pessoa


Note que a classe Pessoa implementa a interface “Serializable”; isto é
necessário, pois, a persistência de objetos exige que a classe associada
implemente esta interface. Note ainda a definição da constante
“serialVersionUID” [no ponto 2]! Esta constante indica a versão
corrente da classe. Note ainda que objetos persistidos com uma versão
da classe de objetos só podem ser recuperados com a mesma versão da
classe e a tentativa de recuperação do objeto usando uma versão de
classe diferente irá resultar em exceção.

Resolução

142
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 89: Aplicação com ficheiros de objetos

Neste código destaca-se os seguintes pontos:


1. Abertura do ficheiro para a escrita e associação ao
ObjectOutputStream
2. Escrita de instância de Pessoa no ficheiro usando o método
“writeObject”. Aqui escreve-se 4 objetos no ficheiro;
3. Abertura do ficheiro para a leitura e associação ao
“ObjectInputStream”;
4. Definição de variáveis de iteração para o ciclo “while”. A
variável “found” indica se a Pessoa procurada foi encontrada
ou não. A variável “endOfFile” indica se chegamos ou não ao
fim do ficheiro;
5. Criação da Pessoa que se pretende recuperar do ficheiro.
Note que esta pessoa possui dados mínimos, a saber, o
código. Este código é necessário pois é usado no método
“equals” da pessoa e permite identificar se duas instâncias
de Pessoa são ou não iguais;
6. Recuperação da instância corrente no ficheiro usando o
método “readObject”. Note que este
143
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

método retorna um “Object”, e aqui fazemos o casting deste


“Object” para Pessoa;
7. Aqui verificamos se o objeto recuperado do ficheiro é igual
a Pessoa que pretendemos recuperar; caso seja imprimimos
os seus dados e marcamos a variável “found” como “true”.
Note que as instruções no ponto 6 e 7 estão envolvidas no
bloco “try”! Isto é necessário porque o método “readObject”
pode rebentar uma exceção se se tiver alcançado o fim do
ficheiro daí que aqui tratamos a exceção em causa
8. Aqui tratamos a exceção “EOFException” que é a exceção
rebentada quando se alcança o fim do ficheiro. No bloco
“catch” informamos que a pessoa procurada não foi
encontrada e mudamos o valor da variável “endOfFile” para
true para indicar que já estamos no fim do ficheiro e garantir
a paragem do ciclo “while”.

Sumário
Nesta unidade temática 3.5 estudamos o processo de serialização e de-
serialização de objetos. Trata-se de um processo que permite a
transferência de objetos por meio de Streams binários. Nesta unidade
temática abordamos essencialmente o processo de persistência e
recuperação de objetos em ficheiros binário recorrendo as classes
ObjectOutputStream e ObjectInputStream. Do ponto de vista de
codificação o uso destas classes torna o processo de persistência e
recuperação de dados mais simples e transparente, no entanto em
termos de performance os resultados não são animadores visto que
este processo é bastante lento e, portanto, desaconselhado em
aplicações de média e grande dimensão.

144
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Exercícios de autoavaliação
Perguntas
1. Explique o que é serialização e de-serialização;
2. Qual é o requisito para a serialização de uma instância de
classe com uso ao ObjectOutputStream?
3. Qual é o requisito para a de-serialização de um objeto
contido num ficheiro com recurso a ObjectInputStream?
4. Por que razão o uso de ficheiros de objetos é
desaconselhado?
5. Elabore um programa que permite armazenar e recuperar
de um ficheiro de objetos instâncias de Conta bancária.
Suponha que cada conta bancária seja descrita pelos
seguintes atributos: número, titular e saldo. O programa
deverá fornecer as seguintes funcionalidades:
• Criar conta e armazena-la no ficheiro;
• Recuperar e visualizar do ficheiro uma conta
bancaria dado o seu número;
Respostas:
1. O processo de serialização é o processo pelo qual o estado
corrente de um objeto é transformado em bytes de modo a
permitir a sua transferência usando Streams. A serialização
envolve sempre uma instância e a classe de objetos a que tal
instância pertence. O processo de recuperação de instância
de uma classe de um ficheiro é conhecido como de-
serialização e consiste na conversão de bytes [armazenados
em disco] em uma instância de classe.
2. Para que um objeto seja serializado usando o
ObjectOutputStream, a classe a que pertence deve
implementar a interface “Serializable”.
3. Para que um objeto seja de-serializado usando o
ObjectInputStream, a classe a usar para o processo deve ser
serializável, isto deve implementar a interface “Serializable”,
além disso esta classe deve ser exatamente a mesma usada
para o processo de serialização deste objeto.
4. O uso de ficheiros de objetos é desaconselhado por
comprometer a performance das aplicações.
5. Resolução
A solução para este problema é composta por duas classes, a classe do
modelo (Conta) que esta representada mais abaixo e a classe
aplicacional (App03_05_04); note que primeiramente apresenta-se o
esqueleto desta classe e mais adiante apresentam-se os métodos da
classe.

145
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 90: Esqueleto da aplicação com ficheiro de objetos

Conteúdo do método “menu”

Figura 91: O menu da aplicação

146
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 92: Conteúdo do método “createConta”

Figura 93: Conteúdo do método “copyOldData”

147
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 94: Conteúdo do método “findConta”

Exercícios para avaliação


Nos números seguintes escolha a afirmação mais correta:
1. Para que um objeto possa ser serializado em um ficheiro é
necessário que:
a) O seu descritor (a classe de objetos) implemente a
interface “Serializable”;
b) O ficheiro exista no disco;
c) O seu descritor (a classe de objetos) e todos os seus
membros (atributos) implementem a interface
“Serializable”;
2. Qual das seguintes afirmações é verdadeira
a) Em todos os casos, o método “readObject” da classe
“ObjectInputStream” recupera o objeto na posição
corrente do ficheiro e avança o cursor para o próximo
objeto;
b) Sempre que o método “readObject” da classe
“ObjectInputStream” for executado com sucesso o
mesmo retorna, em todos os casos uma instância de
“Object”;
c) A invocação do método “readObject” resultará numa
exceção caso se tenha alcançado o fim do ficheiro;

148
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

3. Quando lemos de um ficheiro usando “ObjectInputStream”


como identificamos que alcançamos o fim de um ficheiro?
a) Quando a chamada ao método “readObject” rebenta a
exceção “EOFException”;
b) Quando a invocação do método “available ()” retorna
um número positivo;
c) Não é possível identificar o fim de um ficheiro quando
usamos esta classe.
4. Verdade ou falso que um ficheiro de objetos é também um
ficheiro binário?
a) Verdade;
b) Falso;
c) Pode ser verdade, mas também pode ser falso.
5. Quais são os possíveis problemas que podem ser
enfrentados no processo de persistência e recuperação de
objetos em binários?
a) Incompatibilidade de versões das classes no processo de
de-serialização;
b) Lentidão do processo;
c) As duas opções anteriores estão corretas.
6. Verdade ou falso que, em todo caso um objeto cuja a classe
[a que pertence] implemente a interface “Serializable” pode
ser serializado em um ficheiro binário?
a) Falso;
b) Verdade;
c) Nem falso nem verdade.
7. Qual é a vantagem da persistência de objetos usando
ObjectOutputStream e ObjectInputStream?
a) Não tem nenhuma vantagem pois tem performance
ruim;
b) É um processo simples e transparente;
c) É seguro.
8. Existirá alguma relação entre ObjectOutputStream e
FileOutputStream?
a) Sim, ObjectOutputStream tem na sua composição
FileOutputStream;
b) Sim, FileOutputStream tem na sua composição
ObjectOutputStream;
c) Não, não existe nenhuma relação.
9. A invocação do método “flush” sobre um
ObjectOutputStream
a) Causa a escrita de dados contidos no buffer no ficheiro
associado;
b) Causa a escrita dos dados contidos no buffer no ficheiro
associado e encerra-o;
c) Encerra o ficheiro.

149
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

10. Será verdade que em todo caso a chamada ao método


“readObject” sobre uma variável do tipo ObjectInputStream
irá retornar o objeto corrente de um ficheiro de objetos?
a) Sim;
b) Não;
c) Talvez.
Respostas: 1c, 2c, 3a, 4a, 5c, 6a, 7b, 8a, 9a, 10b.

Unidade temática 3.6: Entrada de dados usando a classe


Scanner

Introdução

Os Streams servem fundamentalmente como fonte de dados ou destino


destes. Até aqui estivemos a tratar de Streams tendo como âmbito o
acesso a ficheiros para a escrita (destino) de dados bem como a
recuperação destes (fonte). No entanto os Streams podem ser usados
para a leitura de dados pelo teclado bem como a visualização de dados
na tela. Nesta unidade temática iremos nos focar nos mecanismos de
leitura de dados a partir do teclado usando para isso a classe Scanner.
Ao completar esta unidade temática 3.6, você deverá ser capaz de:

▪ Compreender: a essência da classe Scanner;


▪ Inicializar: o Scanner para a leitura de dados pelo teclado;
▪ Usar: o Scanner para obter dados a partir do teclado de acordo
Objectivos com o tipo destes.
específicos

Processo de interação entre o utilizador e os programas


A maioria dos programas permite alguma interação com o utilizador.
Através do teclado o usuário pode enviar comandos ao programa ou
submeter dados. Por outro lado, os programas usam a tela para
apresentar informação ao utilizador. Em JAVA a visualização de dados e
leitura de dados pelo teclado é conseguido recorrendo aos Streams.
A visualização de dados na tela é conseguida recorrendo ao Stream
“System.out”, trata-se de um objeto do tipo “PrintStream” que
disponibiliza diversos métodos com o propósito de impressão de dados
na tela. Os métodos como “print” e “println” têm sido usados em
abundância.
A leitura de dados pelo teclado pode ser conseguida recorrendo ao
Stream “System.in” que à semelhança do “System.out” é um Stream do

150
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

tipo InputStreamReader. O processo de leitura de dados é simplificado


quando se recorre a classe Scanner. Trata-se de uma classe que que faz
uso interno da classe InputStreamReader e fornece diversos métodos
que permite a leitura de dados de diferentes tipos de dados. Nesta
unidade temática iremos aprender a essência do Scanner.

Inicialização do Scanner e seu fecho


Para a leitura de dados pelo teclado a classe Scanner deve ser
inicializada recorrendo ao construtor que recebe pelo parâmetro um
InputStreamReader. No trecho de código abaixo ilustra-se um exemplo
de inicialização do Scanner.

Figura 95: Inicialização do Scanner

Neste pedaço de código, cria-se uma instância de Scanner [no ponto 1]


a qual é associada à variável “scanner”. Note que como parâmetro
passamos “System.in” que representa o InputStreamReader
disponibilizado por defeito pelo JAVA.
No ponto 2, é encerrado o Scanner recorrendo ao método “close”. O
encerramento do scanner é importante pois libera o Stream a ele
associado.

Métodos disponibilizado pelo Scanner


O Scanner disponibiliza diversos métodos para a leitura de dados, estes
métodos devem ser aplicados de acordo com o tipo de dado que se
pretende obter a partir do teclado. A tabela abaixo apresenta os
métodos mais comuns usados para a obtenção de dados a partir do
teclado.
Método Tipo de Dados Descrição
Suportado
next() String Obtém uma String
pelo teclado. Note
que este método lê

151
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

apenas o primeiro
“token” ou palavra
caso o utilizador
forneça um texto
com mais de uma
palavra.
nextLine() String Obtém uma String
pelo teclado. Note
que este método
permite ler uma
linha inteira
diferentemente do
método “next()” que
lê apenas a primeira
palavra.
nextBoolean boolean Obtém um boolean
pelo teclado
nextByte byte Obtém um byte pelo
teclado
nextInt int Obtém um int pelo
teclado
nextLong long Obtém um long pelo
teclado
nextFloat float Obtém um float pelo
teclado
nextDouble Obtém um double
pelo teclado

Note que [para os métodos que obtém pelo teclado valores de tipos de
dados primitivos] uma exceção será rebentada caso pelo teclado se
especifique um valor de tipo de dados incompatível.

Interação com o Utilizador usando o Scanner e o PrintWriter


Conforme referido anteriormente, o Scanner e o PrintWriter fornecem
mecanismos para a interação entre o utilizador e o programa. O
PrintWriter permite escrever mensagens na tela, estas mensagens
podem ser de caráter informativo, descritivo, de alerta ou de apoio. O
Scanner fornece mecanismos para o enviar dados ou comandos ao
programa. Normalmente, para a interação com o utilizador, os
programas [que correm na consola] emitem uma mensagem na tela e o
utilizador reage a essa mensagem usando o teclado. O programa
seguinte apresenta um exemplo típico de um programa com alguma
interação com o utilizador. O mesmo tem como pretensão o cálculo da
idade de um individuo.

152
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 96: Exemplo de Interação entre o Utilizador e o Programa

A figura anterior ilustra uma situação típica de um programa que


interage com o utilizador. No ponto 1 e 2 o programa começa por
apresentar mensagem para o utilizador; trata-se de mensagens de
instrução que orientam ao utilizador sobre o que o programa espera
dele. Logo de seguida, usando o método apropriado do Scanner, o
programa obtém do utilizador um dado. No primeiro ponto, o nome e,
no segundo ponto, o ano de nascimento. De seguida, no ponto 3, o
programa efetua algum processamento, neste caso o cálculo da idade.
Note o uso do método “getCurrentYear”; trata-se de um método que
determina o ano corrente, definido no ponto 5. No ponto 4 faz-se a
visualização da informação para o utilizador.

Sumário
Nesta unidade temática 3.6 estudamos os mecanismos de interação do
utilizador com os programas. Basicamente este processo é conseguido
recorrendo aos Streams “InputStreamReader” e “PrintWriter”. O
“PrintWriter” permite a visualização
153
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

de informação na tela e pode rapidamente ser acedido através de


“System.out”. O “InputStreamReader”, para obtenção de dados pelo
teclado e ele pode rapidamente ser acedido através de “System.in”.
Existe uma preferência em usar a classe “Scanner” para a obtenção de
dados pelo teclado pois esta classe torna este processo mais simples e
transparente na medida em que a mesma disponibiliza métodos que
permitem obter pelo teclado dados de tipos específicos de acordo com
a necessidade.

Exercícios de autoavaliação
Perguntas
1. Explica como os programas interagem com o utilizador;
2. Em java quais são as classes usadas para a iteração com o
utilizador;
3. Qual é a forma rápida disponibilizada pelo java para o acesso
às instâncias das classes mencionadas no ponto anterior?
4. Explica a relação entre a classe Scanner e a classe
“InputStreamReader”?
5. Modifique o programa apresentado no tópico “Interação
com o Utilizador usando o Scanner e o PrintWriter” de
modo a usar conceitos de orientação a objetos.
Respostas
1. A interação dos programas com o utilizador é feita através
da visualização de mensagens ao utilizador e mecanismos
que permitem com que este informe dados aos programas
pelo teclado ou pelo mouse.
2. “PrintStream” para visualização de dados e
“InputStreamReader” para a leitura de dados.
3. System.out e System.in, respetivamente.
4. A classe “Scanner” é um “wrapper” da classe
“InputStreamReader”; um scanner usa internamente um
“InputStreamReader” para disponibilizar mecanismos de
leitura de dados pelo teclado.
5. Resolução
A solução para este problema é composta por duas classes, a saber, a
classe “Individuo” que representa a entidade do sistema e a classe
App03_06_06 que representa a aplicação.

154
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 97: Aplicação com interação com Utilizador

Figura 98: A classe Individuo

155
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Exercícios para avaliação


Nos números seguintes escolha a afirmação mais correta:
1. Qual é a relação entre a classe Scanner e InputStreamReader
a) InputStreamReader tem na sua composição Scanner;
b) Scanner tem na sua composição InputStreamReader;
c) Não existe nenhuma relação.
2. Quais são as classes usadas para a visualização de
mensagens na tela e obtenção de dados pelo teclado?
a) Respetivamente, System.out e System.in;
b) Respetivamente, System.in e System.out;
c) Respetivamente “PrintWriter” e “InputStreamReader”
3. Qual das seguintes afirmações é verdadeira?
a) Em todos os casos, o método “nextInt” da classe
“Scanner” retorna um “int”;
b) A chamada do método “close()” da classe Scanner é
obrigatória quando já não se pretende usar o scanner;
c) Em “System.in” “in” é um atributo estático da classe
“System”;
4. Em que consiste “interação de programas com o utilizador”?
a) É o processo pelo qual o programa apresenta mensagens
ao utilizador e este por sua vez envia comandos para o
programa;
b) É o processo pelo qual o utilizador se inteira e
compreende o propósito de um programa;
c) É o processo pelo qual um programa compreende a
intenção do utilizador.
5. Qual é a necessidade de encerrar o Scanner com o método
“close” após a sua utilização?
a) Garante que o mesmo não será usado indevidamente
noutros pontos do programa;
b) Garante que o mesmo será liberado;
c) Garante que o Stream a ele associado fique liberado.
6. Dos vários métodos disponibilizados pela classe Scannerpara
a leitura de dados pelo teclado, qual deles preferirias usar?
a) O método “nextLine” por permitir a leitura de todo tipo
de dados;
b) Aquele que se adequa ao tipo de dados pretendido;
c) Aqueles que permitem ler números inteiros.
7. Qual é a diferença entre o método “nexLine” e “next” da
classe Scanner?
a) O primeiro lê todo o conteúdo da linha corrente, o
Segundo lê a primeira palavra do conteúdo da linha
corrente;

156
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

b) O primeiro lê todo o conteúdo da linha corrente, o


Segundo lê a última palavra do conteúdo da linha
corrente;
c) Não há diferença entre os dois.
8. O trecho de código apresentado mais abaixo ilustra o
construtor da classe Scanner. Sabendo que o parâmetro é
uma classe abstrata e que classes abstratas não possuem
instâncias, que tipo de instâncias serão passados como
parâmetro para este construtor?
a) Instâncias de subclasses da classe InputStream;
b) Instâncias de superclasses da classe InputStream;
c) Este construtor não pode ser invocado.

9. Verdade ou falso que todo o programa deve interagir com o


utilizador?
a) Verdade;
b) Falso;
c) É verdade, mas as vezes é falso.
10. No código apresentado mais abaixo, explique a necessidade
da chamada ao método nextLine na linha 10;
a) Não há necessidade pois a linha lida é ignorada;
b) É necessário para garantir a mudança de linha e permitir
a leitura da frase no ponto 13.
c) Devia se atribuir a chamada nesta linha a uma variável.

157
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Respostas: 1c, 2c, 3c, 4a, 5c, 6c, 7a, 8a, 9b, 10b.

Exercícios do tema

Exercícios de autoavaliação
Perguntas
1. Suponha que os dados da venda de um produto estão
armazenados num ficheiro de texto, conforme ilustrado na
figura abaixo (onde a primeira linha representa o nome do
produto, a segunda linha representa a quantidade e a
terceira linha representa o preço unitário).

a) Elabore um programa que recupera estes dados, acha o


valor total da venda e visualiza os dados na tela no
formato:

b) Use orientação a objetos para modelar a Venda.

158
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

2. Resolva o exercício anterior assumindo que o ficheiro


armazena várias vendas no formato apresentado; isto é,
cada venda é representada por três linhas. [na figura
seguinte ilustra-se um ficheiro com três vendas; estes dados
são apenas ilustrativos]

3. Os dados referentes ao stock de um determinado armazém


estão armazenados num ficheiro de texto (stock.txt)
conforme ilustrado na figura abaixo. (NOTA: use orientação
a objetos para modelar o Stock)

a. Crie um programa que abre o ficheiro (stock.txt) e


imprime todos os produtos nele armazenados. Para cada
produto o programa deverá imprimir o nome e o Stock
disponível (Excluindo o preço unitário)
b. Crie outro programa que permite imprimir a lista de
todos os produtos e o respectivo valor do produto (sub
total). Para cada produto o programa deverá imprimir o
nome e o valor (sub-total) correspondente.
c. Crie outro programa que permite imprimir todos os
dados dos produtos cujo stock disponível é inferior a 40.

159
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

d. Crie outro programa que permite imprimir todos os


dados (incluindo o sub total) de um produto específico
dado o nome do produto.
e. Crie outro programa que permite imprimir o total de
facturação esperado.
4. Elabore um programa que permite ler, pelo teclado, as
temperaturas diárias observadas durante um determinado o
mês de janeiro. Os dados lidos devem ser armazenados num
ficheiro de texto (temperaturas.txt) com o formato indicado
abaixo.

Após a gravação dos dados, o programa deverá abrir o


ficheiro, aceder aos dados e:
a) Achar e visualizar a média das temperaturas máximas;
b) Achar e visualizar a temperatura máxima mais elevada.
Notas:

• O código para a leitura de temperaturas [pelo teclado] e escrita


destes no ficheiro deve ser criado num método chamado
“criarBaseDeDados”.
• A recuperação das temperaturas máximas [do ficheiro] deve ser
feita num método chamado “retrieveData” o qual deverá
retornar um array contendo todas as temperaturas máximas
registadas.
• O cálculo da média deve ser feito num método chamado
“acharMediaTempMax” este método deverá receber pelo
parâmetro o array contendo as temperaturas máximas e
retornar a média.
• A temperatura máxima mais elevada deve ser determinada num
método chamado “acharTempMaxElevada” o qual deverá
receber pelo parâmetro o array contendo as temperaturas
máximas e retornar a temperatura mais elevada.
5. Nota: para este exercício deverá usar como base a classe
ContaOrdem apresentada na unidade temática 2.3 no tópico
“Interfaces” e o respetivo MotorDePersistencia.

160
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Suponha que os dados referentes a contas bancárias (a


ordem) são armazenadas num ficheiro de texto de nome
“contas_ordem.txt”.

Crie uma aplicação que por meio de um menu permite


efetuar o seguinte:
• Criar uma ContaOrdem e armazena-la no ficheiro
mencionado anteriormente;
• Recuperar uma conta específica do ficheiro e visualizá-
la;
• Recuperar uma conta específica do ficheiro e efetuar um
deposito sobre ela e atualizá-la no ficheiro;
• Recuperar uma conta específica do ficheiro e efetuar um
levantamento sobre ela e atualiza-la no ficheiro;
• Recuperar duas contas específicas do ficheiro e efetuar
uma transferência duma das contas para outra e
atualizar as duas contas no ficheiro.
Todos os dados necessários devem ser fornecidos pelo utilizador.
SUGESTÃO:
Para esta aplicação, o ideal é subdividir o código em pequenos métodos,
nomeadamente:
• “public static int menu ()” que apresenta o menu, lê a
opção e retorna;
• “public static void createConta()” que cria uma objeto do
tipo ContaOrdem com base em dados lidos pelo teclado
e armazena-a no ficheiro usando o método “saveToFile”
da classe “MotorDePersistencia”;
• “public static ContaOrdem find ()” que recupera do
ficheiro uma conta bancária dado o número da conta; o
método começa por ler [pelo teclado] o número da
conta, cria um objeto do tipo ContaOrdem e com base
no método “loadFromFile” da classe
“MotorDePersistencia”, busca a conta no ficheiro e
retorna-a;
• “public static void visualizar ()”, que visualiza os dados de
uma conta específica. O método busca a conta usando o
método find e de seguida visualiza na tela a conta em
causa;
• “public static void depositar ()”, efetua um deposito
numa conta específica. O método busca a conta usando
o método “find” e sobre esta conta efetua deposito de
um valor lido pelo teclado. No fim atualiza os dados da

161
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

conta no ficheiro usando o método “updateOnFile” da


classe “MotorDePersistencia”.
• “public static void levantar ()”, efetua um levantamento
numa conta específica. O método busca a conta usando
o método “find” e sobre esta conta efetua levantamento
de um valor lido pelo teclado. No fim atualiza os dados
da conta no ficheiro usando o método “updateOnFile” da
classe “MotorDePersistencia”.
• “public static void transferir ()”, transfere um valor duma
conta para outra. O método começa por buscar a conta
origem e a conta destino usando o método “find”; sobre
a conta origem efetua uma transferência de um valor
lido pelo teclado para a conta destino. No fim atualiza os
dados das contas no ficheiro usando o método
“updateOnFile” da classe “MotorDePersistencia” para
cada uma das contas.
• “main” que por meio de uma estrutura “switch-case”,
invoca os métodos necessários para a execução das
funcionalidades.
Respostas

Exercicío 1

162
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 99: Aplicação Para Recuperação de Venda em Ficheiro

Figura 100: A classe Venda

163
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Exercício 2

Figura 101: Exercício 2

Exercício 3

164
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 102: A classe Stock

Figura 103: Resolução exercício 3a

165
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 104: Resolução exercício 3b

166
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 105: Resolução exercício 3c

167
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 106: Resolução do exercício 3d

168
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 107: Resolução exercício 3e


Exercício 4

169
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 108: Esqueleto resolução exercício 4

170
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 109: O método criarBaseDeDados para o exercício 4

171
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 110: O método retrieveData para o exercício 4

Figura 111: O método acharMediaTemMax para o exercício 4

172
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 112: O método acharTempMaxElevada para o exercício 4


Exercício 5

173
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 113: Esqueleto da resolução do exercício 5

174
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 114: O método menu

Figura 115: O método createConta

175
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 116: O método find

Figura 117: O método visualizar

176
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 118: O método depositar

Figura 119: O método levantar

177
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 120: O método transferir

Figura 121: O método printErr que imprime mensagem de erro

178
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Exercícios para avaliação


Nos números seguintes, escolha a alternativa mais correta.
1. O método “read” da classe FileReader retorna sempre o valor
correspondente ao carater corrente.
a) Sim;
b) Não;
c) Talvez.
2. Qual das seguintes afirmações é verdadeira?
a) O compilador irá dar um erro, sempre que o
programador não fechar o Stream com o método
“close”;
b) O programa terá uma paragem inesperada sempre que
o programador não fechar o Stream com o método
“close”;
c) O programa poderá apresentar comportamento
inesperado sempre que não fechar o Stream com o
método “close”.
3. Normalmente cada tipo de Stream usa duas classes.
a) Sim, uma para a escrita e outra para a leitura de dados;
b) Sim, uma para escrever no ficheiro outra para ler do
ficheiro;
c) Sim, uma para o upload e outra para o download de
dados.
4. O algoritmo usado para a atualização de um ficheiro de texto é
semelhante ao
a) “Copy-Paste”;
b) “Find and Replace”;
c) “Find and Replace” associado ao “Copy-Paste”.
5. Qual é o perigo que o método “flush” dos Streams buferizados
pode trazer?
a) Possibilidade de inconsistência de dados se o mesmo for
mal aplicado;
b) Danificação do dispositivo de armazenamento de dados;
c) Este método pelo contrário garante que os dados sejam
persistidos, portanto não constitui nenhum perigo.
6. Em todos os casos, o método “read” da classe “FileReader”
retorna um inteiro representando o carater corrente.
a) Sim;
b) Talvez;
c) Nem sempre.
7. Em Streams qual é a diferença principal do método “close” e do
“flush”?
a) O método “close” encerra o ficheiro liberando-o e o
“flush” persiste os dados correntes sem liberar o
ficheiro.
179
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

b) Estes dois métodos não têm nenhuma diferença, ambos


persistem os dados no ficheiro;
c) Em todos os casos, os dois persistem os dados no
ficheiro; depois o “close” encerra e libera o ficheiro e o
“flush” não libera o ficheiro.
8. No trecho de código seguinte o que faz a chamada ao método
“trim”?

a) Auxilia na conversão para int;


b) Elimina espaços em branco à esquerda e à direita na
string contida em “elementos[1]”;
c) Elimina espaços em branco à direita da string contida em
“elemento[1]”.
9. Para que servem os Streams?
a) Servem para escrever e ler dados de ficheiros;
b) Servem para a troca de dados entre o programa e diferentes
dispositivos periféricos;
c) Servem para distribuir conteúdos digitais de forma contínua.
10. Qual das seguintes afirmações é verdadeira?
a) O método “split” da classe String costuma aparecer na
resolução de problemas envolvendo ficheiros de texto;
b) Em todo o caso, o método “readLine” de um BufferedReader
retorna uma String;
c) É possível criar um BufferedWriter sem FileWriter.

1b, 2c, 3a, 4c, 5a, 6c, 7c, 8b, 9b, 10a

Referências Bibliográficas

Caelum. Java e Orientação a Objetos. Consultado em maio de 2021.


Disponível em https://www.caelum.com.br/apostila-java-orientacao-
objetos
Oracle. I/O Streams. Consultado em maio de 2021. Disponível em
https://docs.oracle.com/javase/tutorial/essential/io/streams.html
https://www.devmedia.com.br/classe-inputstream-e-outputstream-
em-java/32007
Devmedia. Classe InputStream e OutputStream em Java. Consultado em
maio de 2021. https://www.devmedia.com.br/classe-inputstream-e-
outputstream-em-java/32007
180
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Programiz. Java I/O Streams. Consultado em maio de 2021. Disponível


em https://www.programiz.com/java-programming/io-streams.

181
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

TEMA – IV: TIPOS GENÉRCOS(GENERICS)

Unidade temática 4.1: Tipos e métodos genéricos


Unidade temática 4.2: Herança com classes genéricas
Unidade temática 4.3: Mais em volta de Generics
Unidade temática 4.4: Exercícios deste tema

Unidade temática 4.1: Tipos e métodos genéricos

Introdução
O conceito Generics é um conceito que adiciona poder à linguagem de
programação JAVA; trata-se de um conceito que, conforme veremos ao
longo deste capítulo, reduz a possibilidade de introdução de
inconsistências e erros nos nosso programas bem como flexibiliza o
processo de programação. O conceito Generics é um conceito
relativamente novo na linguagem JAVA, porém tem sido empregado em
diversas aplicações de média e grande porte na medida em que o
mesmo aparece associado ao Collection Framework que é uma
poderosa API do JAVA. Nesta unidade temática iremos introduzir o
conceito Generics apresentando as suas vantagens e a forma como o
mesmo é conseguido; iremos ainda apresentar a sua definição e
exemplos relacionados.
Ao completar esta unidade temática 4.1, você deverá ser capaz de:

▪ Explicar: o conceito Generics;


▪ Explicar: a necessidade do uso de Generics apontando as
vantagens deste conceito;
Objectivos ▪ Criar: e instanciar classes Genéricas e explicar os elementos deste
específicos tipo de classes;
▪ Criar: e invocar métodos genéricos.

Porquê o uso de Generics?


A linguagem de programação JAVA é conhecida como linguagem
compilada, trata-se de uma linguagem que exige que os programas
sejam traduzidos para um formato capaz de ser compreendido pela
máquina virtual (JVM). A compilação é crucial no processo de
desenvolvimento de aplicações pois permite ao programador identificar
violações que poderiam resultar em programas malformados e com
grande potencial de provocar inconsistência de dados. Os tipos
genéricos adicionam a capacidade de verificação e validação dos
programas ainda na fase de codificação. Usando tipos genéricos é
possível identificar [ainda em tempo de codificação] certo tipo de erros
que tradicionalmente não seria
182
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

possível identifica-los. Isto justifica a necessidade do uso de tipos


genéricos.

Tipos Genéricos ou simplesmente Generics são classes de objeto que


permitem trabalhar com o polimorfismo de forma mais segura.
Conforme tratado no tema 2 (pilares da orientação a objetos), o
polimorfismo é um conceito que favorece a abstração e a abstração
permite escrever soluções aplicáveis a diversas situações. As soluções
com abstração e polimorfismo podem favorecer ou levar a situações de
erros inesperados principalmente em projetos de grande porte. Para
melhor entender isto, vamos considerar a classe MotorDePersistencia
representada na figura seguinte.

Figura 122: Motor de persistência

Note que o MotorDePersistencia pode gravar e recuperar do ficheiro


qualquer instância de classe!
Vamos agora considerar o programa apresentado na figura seguinte.
Trata-se de um exemplo bastante trivial e apresenta uma situação
pouco provável em um programa simples, mas com grandes

183
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

possibilidades de se verificar em projetos complexo envolvendo


equipas vastas.

Figura 123: Problemas com abstração e Polimorfismo


Neste trecho de código, no ponto 1, cria-se uma instância de
MotorDePersistencia. No ponto 2, cria-se duas instâncias, uma de
Pessoa e outra de Conta. Mais adiante, no ponto 3, persiste-se estas
duas instâncias recorrendo ao método “saveToFile” do “motor”. Note
que este método escreve o objeto passado pelo parâmetro no ficheiro
“pessoas.txt”. No ponto 4, tenta-se recuperar a conta “1234” do ficheiro
usando o método loadFromFile. Neste ponto podemos destacarum dos
problemas desta solução! O método loadFromFile poderá retornar
instância de qualquer classe e neste ponto o programador,
inadvertidamente tenta fazer casting do objeto recuperado para
“Pessoa”. Em tempo de compilação nenhum problema será reportado,
mas em tempo de execução uma exceção do tipo “ClassCastException”
será rebentada pois a chamada do método “loadFromFile” neste ponto
irá retornar uma instância de Conta e não de Pessoa.
Em aplicações complexas este tipo de situações pode ocorrer pois o uso
de abstração e polimorfismo é quase inevitável. É aí onde entram os
tipos genéricos pois permitem ao compilador alertar sobre situações
como esta. Mais adiante traremos uma solução para o problema
recentemente apresentado

Definindo um Tipo Genérico


Um tipo genérico é uma classe que permite na sua definição a passagem
de tipos de dados [para os seus atributos ou outros elementos] por meio
de parâmetros. Estes parâmetros são usados para garantir que o
uso de polimorfismo seja mais seguro

184
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

na medida em que permite que uma classe que trabalha com


polimorfismo possa definir a cada momento que tipo de dados é
suportado.
A definição de classe genérica simples segue o padrão apresentado
abaixo.

Figura 124: Definição de Tipo Genérico

Note o uso de colchetes (<>) e a letra “T”. Neste caso “T” entra como
parâmetro para a classe e pode ser referenciado como tipo ao longo da
classe. Note que a letra “T” pode ser substituída por qualquer outra
letra embora a boa prática convencione que se use as letras de acordo
com o tipo de parâmetro que se pretende usar, a saber: (1) “E” para
elementos (2) “K” para chaves (3) “N” para números (4) “T” para tipos
(5) “V” para valores.
Agora, vamos reescrever o nosso MotorDePersistencia como tipo
genérico.

185
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 125: Motor de Persistência como Generic

Note que o nosso MotorDePersistencia agora foi definido com um


parâmetro [ponto 1]; este parâmetro transforma a nossa classe como
genérica. Note ainda que os métodos “saveToFile” e “loadFromFile”
recebem agora referências a “T” (pontos 2 e 3) e o retorno deste último
método agora é “T”. Este é o poder de Generics! Deixamos de nos
amarrar a classe “Object” e passamos a usar um tipo genérico. Isto
garante que sempre que criarmos um MotorDePersistencia o mesmo
irá persistir apenas objetos de um tipo específico evitando a
possibilidade de “confusão” de tipos tratados pelo motor.

Instanciação e manipulação de classes Genéricas


Vamos reescrever o nosso programa AppComPersistencia apresentado
anteriormente.

186
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 126: Inicialização de classe Genérica


Neste programa podemos destacar algumas coisas:
Ponto 1: definição da variável do tipo genérico (motor). Note que aqui
usamos como tipo a classe MotorDePersistencia com o parâmetro
Pessoa a ser passado entre “<>”; este parâmetro representa o tipo
Pessoa e substitui o tipo genérico “T”. Isto implica que o nosso
MotorDePersistencia fique associado a instâncias de Pessoa.
Ponto 2: instanciamos a nossa classe genérica. Note que usamos o
mesmo tipo que usamos na definição da variável motor;
Ponto 3: passamos instância de Pessoa para o método “saveToFile” do
motor;
Ponto 4: aqui passamos uma instância de Conta para o método
“saveToFile”. Esta chamada irá resultar em erro de compilação pois
definimos o nosso motor para suportar instâncias de Pessoa. Caso
quiséssemos persistir instâncias de Conta teríamos de criar um outro
motor (instância de MotorDePersistencia) com o parâmetro Conta
[MotorDePersistencia<Conta>] o qual iria aceitar objetos do tipo Conta.
Ponto 5: tentamos recuperar uma Conta usando um motor que foi
definido com parâmetro “Pessoa”; esta instrução não irá resultar em
erro de compilação pois o motor usado suporta apenas instâncias de
Pessoa.

187
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Neste exemplo podemos ver como o uso de classes genéricas reduz a


possibilidade de erros em aplicações.
Os tipos genéricos são largamente usados nas coleções do JAVA as quais
serão abordadas com profundidade no capítulo 5.

Métodos Genéricos
À semelhança de classes, é possível introduzir parâmetros genéricos a
métodos. O trecho de código seguinte ilustra uma classe que faz uso de
um método genérico.

Figura 127: Método Genérico

Nesta figura temos um exemplo de um método genérico, o método


“find”. Os métodos genéricos recebem o parâmetro genérico antes do
tipo de dados de retorno [ponto 1]. Este parâmetro genérico deve
entrar para o método como tipo de dados de um dos parâmetros de
entrada do método [ponto 3] ou entrar como parte do tipo de dados
genérico de um dos parâmetros do método [ponto 2]. O parâmetro
pode ainda servir como tipo de dados dentro do método ou ser usado
como tipo de dados de retorno [ponto 4].

No ponto 5, temos o exemplo de invocação do método “find”. A


invocação deste método obriga que o MotorDePersistencia passado
pelo parâmetro seja parametrizado com o mesmo tipo de dados
passado pelo segundo parâmetro, neste caso está-se a trabalhar com o
tipo de dados Pessoa. Esta é mais uma vantagem de tipos genéricos.
Aqui qualquer tentativa de misturar tipos de dados será evidenciada e
rejeitada ainda em tempo de compilação.

188
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Sumário
Nesta unidade temática 4.1 introduzimos o conceito Generics. Trata-se
de um conceito largamente usado junto com o polimorfismo e
abstração. Os tipos de dados genéricos reduzem a possibilidade de
erros relacionados com incompatibilidade de dados em programas
complexos na medida em que garante que estes tipos de erros sejam
identificados ainda em tempo de codificação.

Exercícios de autoavaliação
Perguntas
1. O que é um tipo de dados genérico?
2. Como é criado um tipo de dados genérico?
3. Como se instancia um tipo de dados genérico?
4. Quais são as vantagens do uso de Generics?
5. O trecho de código abaixo, não compila, justifica porquê?

Respostas
1. Um tipo genérico é uma classe que permite na sua definição
a passagem de tipos de dados por meio de parâmetros. Estes
parâmetros são usados para garantir que o uso de
polimorfismo seja mais seguro na medida em que permite
que uma classe que trabalha com polimorfismo possa definir
a cada momento que tipo de dados é suportado.
2. Uma classe genérica na sua definição inclui em colchetes
(<>) o tipo de dados que representa o parâmetro, este
parâmetro aparece imediatamente a seguir ao identificador
da classe.
3. A Instanciação um tipo de dados genérico é feita do mesmo
jeito como se instancia um tipo normal, a única diferença é
que no tipo genérico deve-se passar entre colchetes o tipo
específico representando o parâmetro.

189
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

4. Tipos Genéricos ou simplesmente Generics são classes de


objeto que permitem trabalhar com o polimorfismo de
forma mais segura.
5. O trecho de código em causa não compila porque à variável
“c” atribui-se um valor incompatível.

Exercícios para avaliação


Nos números seguintes escolha a afirmação mais correta.
1. O que é um tipo de dados genérico?
a) É um tipo de dados desconhecido no momento da criação da
classe;
b) É um parâmetro que pode tomar múltiplos tipos;
c) É um tipo que pode ser associado a outros tipos por meio de
parâmetro.
2. Na declaração “List<K> T = new ArrayList<K> ()”
a) “K” é um parâmetro genérico;
b) “K” é um tipo representando uma ocorrência de um
parâmetro específico;
c) “K” é um parâmetro do tipo “Key” (Chave);
Das seguintes afirmações selecione aquelas que são verdadeiras:
3. Os tipos genéricos existem desde as primeiras versões do JAVA;
4. O uso de Generics alarga o espectro de abstração;
5. O uso de Generics minimiza a possibilidade de erros de casting;
6. Em uma classe genérica o parâmetro poderá ser de qualquer letra.
7. Em uma classe genérica é mais indicado o uso das seguintes letras
para parâmetros: “E”, “K”, “N”, “T” e “V”.
8. O efeito de tipos genérico é percebido em tempo de execução;
9. O efeito de tipos genérico é percebido em tempo de codificação.
10. Os tipos genéricos estão intrinsecamente ligados ao
polimorfismo.

Respostas: 1c, 2b, 3a – F, 3b – F, 3c – V, 3d – V, 3e – V, 3f – F, 3g – V, 3h


– V.

190
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Unidade temática 4.2. Subtipos com tipos genéricos

Introdução
A herança é um conceito da linguagem JAVA que adiciona poder a
linguagem; este conceito foi tratado de forma exaustiva no tema II.
Interface é outro conceito que aparece lado a lado com herança e juntos
formam as bases para o polimorfismo e a abstração. Nesta unidade
temática, introduzimos o conceito herança e interface associados aos
tipos de dados genérico. A herança com tipos de dados genéricos é
ligeiramente diferente da herança tradicional daí a importância de se
debruçar sobre este conceito.
Ao completar esta unidade temática 4.2, você deverá ser capaz de:

▪ Explicar: diferença entre herança tradicional e herança com tipos


genéricos;
▪ Estabelecer: uma relação de herança com tipos genéricos;
Objectivos ▪ Criar: e implementar interfaces genéricas;
específicos ▪ Fazer: uso de tipos genérico com herança;
▪ Aplicar: polimorfismo com tipos genéricos

Herança com tipos de dados genéricos


A herança entre tipos de dados (classes de objetos) é conseguida
estendendo a superclasse em subclasse. A subclasse herda os atributos
e métodos da superclasse. A herança é o princípio para o polimorfismo.
Podemos ver um exemplo de polimorfismo no ponto 2 do trecho de
código apresentado a abaixo onde Professor é subclasse de
Trabalhador.

A herança e polimorfismo em tipos de dados genéricos é ligeiramente


diferente. Por exemplo, o trecho de código abaixo não compila.

191
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Embora a classe Professor seja subclasse de Trabalhador, a atribuição


feita no ponto 1 não está correcta pois
MotorDePersistencia<Professor> não é subclasse de
MotorDePersistencia<Trabalhador>.
A herança entre tipos genéricos deve ser definida ainda na fase de
criação da classe de objetos e isto pode ser conseguido de duas formas:
(1) estendendo a classe genérica passando pelo parâmetro um tipo
específico7; (2) definindo a classe como genérica e estendendo ao
mesmo tempo a classe genérica . As figuras seguintes apresentam por
meio de um exemplo as duas formas de estender uma subclasse da
classe genérica MotorDePersistencia apresentada na unidade temática
anterior.

Figura 128: Subclasse especifica de um tipo Genérico

Aqui temos um exemplo de estabelecimento de relação de herança


entre a classe MotorDePersistenciaPessoa e a classe
MotorDePersistencia. Neste caso a subclasse representa uma
ocorrência específica do tipo genérico e a mesma deixou de ser
genérica.
O exemplo a seguir ilustra uma situação em que a subclasse também é
genérica.

7
A herança pode ser ainda conseguida implementado uma interface genérica

192
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 129: Subclasse genérica de um tipo genérico


Note que quer a subclasse quer a superclasse usam o mesmo parâmetro
“T”.

Interfaces genéricas e sua implementação


A criação de interfaces genéricas segue a mesma lógica de classes
genéricas, através de definição de parâmetros associados ao nome da
interface. O trecho de código seguinte ilustra um exemplo de definição
de uma interface genérica.

Figura 130: Interface Genérica


A implementação de interfaces genérica assemelha-se a herança com
tipos genéricos e pode ser feita igualmente de duas formas (1)
implementando a interface genérica passando lhe um tipo específico
pelo parâmetro ou (2) implementando a interface genérica e definir a
classe também como genérica usando o mesmo parâmetro dainterface.
Os exemplos seguintes ilustram as duas formas de implementação de
interface genérica.

193
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 131: Implementação de Interface genérica em uma genérica

Figura 132: Implementação específica de uma interface genérica

Note que na implementação específica de interface genérica, o


parâmetro é substituído por um tipo específico, no caso a classe Pessoa!

Polimorfismo com tipos genéricos


Tal como o polimorfismo tradicional, o polimorfismo com tipos
genéricos é conseguido referenciando instâncias de subclasses por
meio de superclasses ou interface.
O trecho de código seguinte ilustra alguns exemplos de polimorfismo
com tipos genéricos.

194
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 133: Exemplo de polimorfismo com tipos genéricos

Sumário
Nesta unidade temática 4.2 abordamos os subtipos de tipos genéricos.
Um subtipo de tipo genérico pode ser conseguido por meio de herança
com tipos genéricos ou por meio da implementação de interface
genérica.

Exercícios de autoavaliação
Perguntas
1. Explica como podem ser criados subtipos de tipos genéricos;
2. Como são criadas interfaces genéricas?
3. Existirá alguma diferença entre interfaces genéricas e
interfaces tradicionais? Se sim, quais?
4. Será possível aplicar o conceito de polimorfismo com tipos
genéricos? Se explica como.
5. Supondo que Carro implementa Automóvel, a instrução
“List<Automovel> list = new ArrayList<Carro>();” estaria
correta? Justifique.
Respostas
1. A herança entre tipos genéricos pode ser conseguida de duas
formas: (1) estendendo a classe genérica passando pelo
parâmetro um tipo específico; (2) definindo a classe como
genérica e estendendo ao mesmo tempo a classegenérica;
2. A interface genérica é definida com a indicação de
parâmetro no fim do identificador da interface.
3. Sim, existe diferenças, dentre elas: (1) a definição de
variáveis de interface genérica é acompanhada pelo
parâmetro correspondente. (2) as interfaces genéricas
aceitam entrada de parâmetro na sua definição.
4. Sim, é possível e aplica-se da mesma forma que com os tipos
normais. Variáveis de superclasses podem ser usadas para
fazer referência a instâncias das subclasses.
5. Não! Pois ArrayList<Carro> não é subtipo de List<
Automovel>.

195
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Exercícios para avaliação


Nos números seguintes escolha a afirmação mais correcta
1. Se “ArrayList<T>” implementa a interface “List<T>” então a
instrução “List<T> list = new ArrayList<T> ();”
a) Pode estar correta;
b) Pode estar errada;
c) As opções “a” e “b” podem estar corretas.
2. A instrução “List<Object> k = new MyList ();” …
a) Estaria correta se MyList implementasse “List<Object>”
b) Estaria correta se MyList implementasse ou estendesse
“List<Object>”
c) Estaria correta se MyList implementasse ou estendesse
“List<T>”.
3. Na definição “public class Robotic extends
SRobotic<TipoCombustivel>”
a) TipoCombustivel é um parâmetro genérico;
b) TipoCombustivel é um parâmetro específico;
c) TipoCombustivel pode ser parâmetro genérico ou
específico.
4. Como se criam subtipos genéricos?
a) Estendendo uma classe genérica ou implementando
uma interface genérica;
b) Estendendo qualquer tipo de classe e definindo
parâmetro genérico para esta nova classe;
c) As duas opções anteriores estão corretas.
5. Se a classe genérica Machine<T> implementa a interface não
genérica Robotic, então
a) “Robotic r = new Machine<Object>()” não pode estar
correto;
b) “Robotic r = new Machine<Object>()” pode estar
correto;
c) “Robotic r = new Machine<Object>()” está correto.
6. Verdadeiro ou falso que os tipos genéricos alargam o
espectro do polimorfismo.
a) Verdade;
196
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

b) Falso;
c) Nem verdadeiro, nem falso.
7. Qual das seguintes afirmações é correta?
a) Os parâmetros em tipos genéricos alargam o
polimorfismo;
b) Os parâmetros em tipos genéricos garantem uso seguro
de polimorfismo;
c) As duas opções anteriores estão corretas.
8. Uma subclasse de uma classe genérica é também uma classe
genérica.
a) Sim, sempre;
b) Sim, às vezes;
c) Não, nunca.
9. No código apresentado mais abaixo, qual é o tipo de retorno
da chamada ao método “doJob” na linha 6?
a) Conta;
b) ContaOrdem;
c) T.

10. O código apresentado mais abaixo apresenta alguns


problemas de compilação na linha 10. Na tua opinião, o que
pode estar errado neste código?
a) A classes SuperMotor e MotorBasico, podem não ser
genéricos;
b) O tipo passado pelo parâmetro pode não existir;
c) Os dois problemas apresentados nos pontos anteriores
podem ambos estarem presentes.

197
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Respostas: 1c, 2b, 3a, 4a, 5b, 6a, 7c, 8b, 9b, 10c.

Unidade temática 4.3: Mais em volta de Generics

Introdução
O tema Generics é bastante vasto e contem tópicos bastante avançados
e alguns complexos. Este capítulo pretendia apenas fazer uma
introdução do tema Generics para fornecer as bases para o tema 5 que
trata sobre coleções parametrizadas. No entanto vamos nesta unidade
temática 4.3 apresentar ao alto alguns tópicos que poderá encontrar
em volta de Generics.
Ao completar esta unidade temática 4.3, você deverá ser capaz de:

▪ Compreender: e aplicar classe genéricas com múltiplos


parâmetros;
▪ Compreender: e aplicar “wildcards”;
Objectivos ▪ Diferenciar: “wildcard” de parâmetros genéricos e saber quando
específicos aplicar um ou outro;
▪ Compreender: o uso de “extends” com parâmetros genéricos e
“wildcards”;

Múltiplos parâmetros em um tipo genérico


As classes e interfaces genéricas podem receber mais de um parâmetro,
bastando para isso especificar os múltiplos parâmetros separados por
vírgula. Abaixo ilustra-se um exemplo envolvendo interface e classe
genéricas com dois parâmetros.

198
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

“Wildcard”
Em Generics, “wildcard” permite representar uma classe genérica ao
nível da superclasse “Object”. Isto é, um “wildcard” permite que uma
determinada classe genérica possa ser usada para referenciar qualquer
instância de qualquer outro tipo daquela classe genérica. Os “wildcard”
são criados recorrendo ao parâmetro “<?>”; este parâmetro é
conhecido como “tipo desconhecido” e pode representar qualquer tipo
de dados. Abaixo temos um exemplo de aplicação de “wildcard”.

Figura 134: Exemplo de "Wildcard"

Note que o método “manejarMotor” [no ponto 5] recebe um


MotorDePersistencia de tipo desconhecido (“?”). Por este parâmetro
pode ser passado MotorDePersistencia de qualquer tipo. Nos pontos 1
e 2, cria-se dois MotorDePersistencia, um de tipo Pessoa e outro de tipo
Conta. Estes “motores” ficam associados a variáveis do tipo
“MotorDePersistencia<?>”. Note que no ponto 4 invocamos o método
“manejarMotor” passando primeiro tipos com “wildcard” e uma
referência de MotorDePersistencia do tipo ContaOrdem.
Um tipo “wildcard” não pode ser manejado com parâmetros genéricos.
Por exemplo, o trecho de código abaixo não compila!

199
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 135: Segurança dos wildcards

As instruções 2 e 3 não compilam, pois, a variável “motor” é um


wildcard e o método “saveToFile” recebe um tipo definido e wildcard
define tipos indefinidos.

Os tipos wildcard existem para flexibilizar e alargar o uso do


polimorfismo com tipos genéricos, pois os tipos genéricos são
bastantes rígidos na questão de polimorfismo.

Quando usar wildcard e quando usar tipos parametrizados


Os tipos parametrizados e os wildcards possuem algumas diferenças e
é importante perceber tais diferenças de modo a fazer uso adequado
de um ou do outro.
Um tipo de dados parametrizado, é indicado na criação de métodos
cujos parâmetros de entrada estão diretamente relacionados com o
tipo de dados de retorno. O exemplo abaixo ilustra a situação aqui
descrita.

Figura 136: Uso de métodos parametrizados

Note que o método “loadObject”, recebe um tipo de dados


parametrizado e o mesmo tipo é usado como tipo de dados de retorno.
Os métodos com “wildcard”, são indicados para situações em que o
parâmetro de entrada não tem nenhuma relação com o tipo de dados
de retorno. Conforme referido, este tipo de métodos alarga o uso de
polimorfismo tornando os métodos mais usuais.

200
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

O uso de “extends” com tipos genéricos


Em Generics é possível definir um parâmetro com subclasse de uma
outra classe. Isto alarga o uso do método ou da classe parametrizada na
medida em que possibilita a invocação com instâncias de múltiplos
tipos. A figura seguinte ilustra uma classe de objeto que faz uso do
“extends” na definição de parâmetros.

Figura 137: Uso do "Extends"


No exemplo acima, o parâmetro “T” poderá [no momento da
instanciação da classe MotorPersistenciaIndividuo] ser substituído por
qualquer classe que seja subclasse de Individuo ou pela própria classe
Indivíduo.
No ponto 2 o uso de “extends” é aplicado com wildcard. Aqui também,
ao método “parseToIndividuo” poderá ser passado qualquer “List” de
subclasse de Indivíduo ou do próprio Indivíduo.
Neste contexto, o “extends” poderá ser usado também com interfaces
indicado que o parâmetro poderá ser qualquer classe que implemente
tal interface.
A figura seguinte ilustra a instanciação de classe genérica com
“extends” bem como a invocação de método com “extends”. Neste
exemplo considera-se que a classe Funcionário é subclasse da classe
Indivíduo.

201
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 138: Aplicação de tipos e métodos genéricos com "extends"

“Tipos brutos” (Raw Types)


Tipos brutos é o nome que se dá aos tipos genéricos quando são
referenciados sem parâmetros. O uso de tipos brutos anula todas as
vantagens de tipos genéricos pois possibilita o uso de múltiplos tipos de
objetos como parâmetro aos métodos de uma classe parametrizada.
Os tipos brutos são definidos omitindo o parâmetro. O exemplo abaixo
ilustra o uso da classe MotorDePersistencia [apresentada na unidade
temática 4.1] como tipo bruto.

Figura 139: Tipos genéricos brutos


Note que a classe MotorDePersistencia, instanciada no ponto 1, é uma
classe genérica, no entanto nenhum parâmetro foi indicado; estamos
aqui perante o uso de um tipo bruto.
Note ainda que no ponto 2, invocamos o método “saveToFile”
passando-lhe instâncias de diferentes classes! Claramente isto anula
todas as vantagens do uso de tipos genéricos daí que o uso de tipos
brutos é desaconselhado. O compilador irá emitir advertências sempre
que detetar o uso de tipos brutos.
Os tipos brutos existem para garantir que aplicações mais antigas
possam funcionar nas versões mais recentes do JAVA.

202
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Sumário
Nesta unidade temática 4.3 trouxemos alguns conceitos que poderão
ser encontrados em volta do tema Generics. São conceitos avançados e
que contribuem para a criação de aplicações com largo espetro de
abrangência. São eles, os “Wildcards”, uso de “Múltiplos parâmetros” e
“Tipos brutos”. Sem dúvidas, além destes conceitos poderá encontrar
outros que estão fora do âmbito deste manual.

Exercícios de autoavaliação
Perguntas
1. Qual é o número máximo de parâmetros que se pode definir
em uma classe genérica?
2. O que é um tipo bruto;
3. Existe alguma vantagem em usar tipos brutos;
4. Explica porque razão os tipos brutos são desaconselhados?
5. Explica em que circunstâncias se indica o uso de “wildcards”
e em que circunstâncias se indica o uso de tipos genéricos.
Respostas
1. Não existe uma quantidade definida para a quantidade de
parâmetros em tipos de dados genéricos.
2. Tipos brutos é o nome que se dá aos tipos genéricos quando são
referenciados sem parâmetros.
3. Sim! Garante a continuidade de sistemas legados.
4. O uso de tipos brutos anula todas as vantagens de tipos genéricos
pois possibilita o uso de múltiplos tipos de objetos como
parâmetro aos métodos de uma classe parametrizada.
5. Um tipo de dados parametrizado, é indicado na criação de
métodos cujos parâmetros de entrada estão diretamente
relacionados com o tipo de dados de retorno. Os métodos com
wildcard, são indicados para situações em que o parâmetro de
entrada não tem nenhuma relação com o tipo de dados de retorno.

Exercícios para avaliação


Nos números seguintes escolha a afirmação mais correta:
1. Na expressão <T extends Carro>
a) Carro é uma classe;
b) Carro é uma interface;
c) Carro é uma classe ou interface
2. Qual é a importância de tipos brutos

203
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

a) Os tipos brutos não são importantes pois o uso deles anula


todas as vantagens das classes genéricas;
b) Os tipos brutos facilitam a vida do programador na
medida em que não fica limitado a manejar as instâncias
com parâmetros específicos;
c) Embora os tipos brutos sejam problemáticos, eles
garantem a continuação dos sistemas legados (ou
obsoletos)
3. Em Generics, os “wildcards” são usados para
a) Para criar novos tipos;
b) Para definir variáveis;
c) As opções a) e b) estão corretas.
4. Em Generics o que se pode dizer sobre “wildcards”?
a) Que eles facilitam a migração de sistemas legados para
novas abordagens;
b) Que eles anulam o propósito de tipos genéricos;
c) Eles alargam o uso de polimorfismo.
5. O que se pode dizer da instrução “Robotic<? extends
Object> v;”
a) Que o trecho “extends Object” é desnecessário;
b) Que o trecho “extends Object” é necessário;
c) Que o trecho “extends Object” pode ser necessário;
6. Na expressão “public class Machine <T extends Conta>”,
a) “extends indica que a classe Machine é subclasse de
Conta”;
b) Indica que o parâmetro T é subclasse de Conta;
c) Indica que o parâmetro T deverá ser subclasse de Conta.
7. Na expressão “public class Machine <? extends Conta>”, o
que está errado?
a) A palavra “extends” está mal colocada;
b) A interrogação está mal colocada;
c) A classe Conta está mal colocada.
8. Verdadeiro ou falso que em Generics os wildcards só podem
ser usados nos parâmetros de entrada de métodos?
a) Verdade;
b) Falso;
c) Pode ser verdade, mas outras vezes falso.
9. Existirá alguma diferença relevante entre os dois métodos
apresentados no código mais abaixo?
a) Não, os dois podem receber parâmetros do mesmo tipo;

204
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

b) Sim, um suporta tipos brutos e outro, tipos específicos;


c) As duas opções anteriores estão corretas.

10. Qual é o output do programa App03 apresentado mais


abaixo?
a) “Doing operation on generic”
b) “Doing operation on Object”
c) O programa não produz nenhum output.

Respostas: 1c, 2c, 3b, 4c, 5c, 6c, 7b, 8b, 9a, 10a.

205
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Exercícios do tema

Exercícios de autoavaliação
Perguntas
1. O que é um tipo genérico e como o mesmo é definido?
2. Justifique a necessidade do uso de tipos genéricos.
3. O que é um tipo de dados bruto? Explique em que
circunstâncias usarias este tipo de dados.
4. Sugira um problema em que achas que faria sentido usar um
tipo de dados genérico (seja classe ou interface).
5. Discuta o tema “Subtipos de tipos genérico”.
Respostas
1. Um tipo genérico é um tipo que na sua definição inclui um
parâmetro de entrada. Os tipos genéricos podem ainda estar
associados a métodos. O parâmetro genérico representa
uma entrada para a classe ou para o método. Os tipos
genéricos são definidos recorrendo a colchetes e nestes
figura o parâmetro genérico.
2. Os tipos genéricos garantem consistência de tipos quando se
trabalha com polimorfismo e abstração pois com eles o
programador define de forma genérica uma relação estrita
entre a classe e os seus elementos.
3. Um tipo bruto corresponde a uma referência a uma classe
genérica sem o parâmetro associado. Este tipo é usado em
circunstâncias em que não existe necessidade de diferenciar
os parâmetros associados a uma classe genérica.
4. Pode se dar vários exemplos, um deles é o que foi
apresentado ao longo deste tema, o exemplo de motor de
persistência. Faz sentido que este motor use parâmetro
genérico para garantir que não se crie uma “salada russa” ao
persistir e recuperar objetos persistidos. O uso de parâmetro
nesta classe garante que apenas objetos de um tipo podem
ser persistido em um determinado ficheiro; e conforme
ilustrado no exemplo, sem definir parâmetro, há um risco de
se persistir um objeto de um tipo e depois tentar se
recuperar objeto de um tipo completamente diferente.
5. Os subtipos de tipos genéricos podem ser criados de duas
formas: (1) estendendo a classe genérica passando pelo
parâmetro um tipo específico; (2) definindo a classe como
genérica e estendendo ao mesmo tempo a classe genérica.

206
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Exercícios para avaliação


Nos números seguintes escolha a opção mais correta.
1. Que tipo de problemas as classes genéricas resolvem?
a) Problemas relacionados com a incompatibilidade de
tipos de dados;
b) Problemas relacionados com a segurança de dados;
c) Problema relacionados com a integridade de dados.
2. Os tipos de dados genéricos estão intrinsecamente ligados
à?
a) Polimorfismo;
b) Herança;
c) Encapsulamento.
3. Na definição “public class Robotic<TipoCombustivel>”
a) TipoCombustivel é um parâmetro genérico;
b) TipoCombustivel é um parâmetro específico;
c) TipoCombustivel pode ser parâmetro genérico ou
específico.
4. O uso correto de tipos genéricos
a) Possibilita uma programação mais transparente;
b) Reduz a necessidade de uso de casting;
c) As duas opções anteriores estão corretas.
5. Se a classe ContaPrazo é subclasse de Conta, então
a) “Bank<Conta> lC = new Bank <ContaPrazo>();” faz
referência a polimorfismo;
b) “Bank <Conta> lC = new Bank <ContaPrazo>();” faz
referência a abstração;
c) “Bank <Conta> lC = new Bank <ContaPrazo>();” não pode
estar correta.
6. Os tipos de dados genéricos
a) Permitem passar parâmetros as classes através de
métodos;
b) Permitem passar parâmetros através dos construtores;
c) Permitem associar classes/métodos a outros tipos de
forma dinâmica.

207
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

7. Na definição “public class Robotic<TipoCombustivel>


extends SRobotic<TipoCombustivel>”
a) TipoCombustivel é um parâmetro genérico;
b) TipoCombustivel é um parâmetro específico;
c) TipoCombustivel pode ser parâmetro genérico ou
específico.
8. Em que momento se nota uma das vantagens dos tipos
genéricos?
a) Codificação;
b) Compilação;
c) Execução.
9. Os parâmetros dos tipos de dados genéricos podem ser
aplicados
a) Como tipos de dados dos atributos da classe;
b) Como tipos de dados para os parâmetros de métodos
bem como tipos de dados de retorno destes;
c) As duas opções anteriores estão corretas.
10. Considere o trecho de código apresentado mais abaixo. Qual
é o tipo de dados de retorno da chamada ao método “doJob”
na linha 4?
a) T;
b) Conta;
c) A chamada não tem retorno.

Respostas: 1a, 2a, 3b, 4a, 5c, 6c, 7c, 8a, 9b, 10c.

208
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Referências Bibliográficas

Caelum. Java e Orientação a Objetos. Consultado em setembro de


2021. Disponível em https://www.caelum.com.br/apostila-java-
orientacao-objetos
Oracle. Generics. Consultado em setembro de 2021. Disponível em
http://docs.oracle.com/javase/tutorial/extra/generics/index.html.

209
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

TEMA – V: Estudo particular de Coleções Parametrizadas (Collections Framework)

Unidade temática 5.1: Introdução ao “collections framework”.


Unidade temática 5.2: As listas (List).
Unidade temática 5.3: Os conjuntos (Set)
Unidade temática 5.4: Os mapas (Map)
Unidade temática 5.6. Exercícios deste tema

Unidade temática 4.1. Introdução ao Collections


Framework

Introdução
Collections Framework é um conjunto de classes, interfaces e
algoritmos que permitem representar e manipular estruturas de dados
complexos; basicamente, estas estruturas permitem armazenar os
dados em forma de coleções ao mesmo tempo fornecendo mecanismos
e algoritmos sofisticados de recuperação de dados nessas estruturas.
Nesta unidade temática vamos introduzir este Framework apresentado
os seus componentes essenciais e a vantagem de uso do mesmo quer
em aplicações pequenas quer em grandes aplicações.
Ao completar esta unidade temática 5.1, você deverá ser capaz de:

▪ Compreender: a necessidade de uso de Collections Framework


▪ Enumerar: as vantagens do uso do Collections Framework;
▪ Listar: os componentes do Collections Framework;
Objectivos
específicos

Uma introdução ao Collections Framework


Tradicionalmente, as estruturas de dados usadas para manejar coleções
de dados sempre foram os Arrays. O uso de arrays, torna possível o
armazenamento e recuperação de vários dados numa mesma variável.
Por exemplo, usando um único array, conseguimos armazenar e
recuperar os dados de uma lista Estudantes tratados num sistema de
geração de pauta de frequência.
Apesar da possibilidade que os arrays nos dão, de armazenar dados com
características comuns, eles possuem um monte de inconvenientes; por
exemplo, a recuperação de dados em arrays é muito trabalhosa; o
dimensionamento do array é estático, isto é, o tamanho deste define-
se no princípio e não é possível redimensionar quando há necessidade
de colocar mais dados no array.

210
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Collections Framework foi criado exatamente para eliminar as lacunas


dos arrays. Conforme será apresentado ao longo deste capítulo, as
classes do Collections Framework flexibilizam em muito o processo de
armazenamento, recuperação e manipulação de dados com
características comuns em coleções. Além disso, a criação de aplicações
de média e grande porte fica facilitada com a possibilidade de uso da
vasta gama de coleções disponibilizadas pelo JAVA.
As bases do Collections Framework assentam em inúmeras interfaces
que permitem abstrair as diversas coleções disponibilizadas pelo JAVA.
Conforme é sabido, o uso de interfaces flexibiliza a implementação de
soluções na medida em que “desamarra” parte do código a
implantações específicas possibilitando desta forma uma mudança
rápida de uma determinada implementação para outra. No topo das
interfaces está a interface “Collection” e a interface “Map”. Tudo dentro
do Collections Framework gira essencialmente em volta destas duas
interfaces. Abaixo destas interfaces temos por um lado List, Set, Queue,
e Deque que são descendentes de Collection e por outro lado,
SortedMap que é descendente do Map. A figura abaixo ilustra
visualmente a essência das interfaces do Collections Framework.

Figura 140: Interfaces bases de Collections Framework


Note que todas as interfaces do Collections Framework são genéricas, e
as usas implementações, também. Por exemplo, a definição da
interface Collection é

211
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Isto significa que cada coleção estará sempre associada a um tipo


especifico. O mesmo acontece com Map, embora esta última tenha dois
parâmetros genéricos.
Além das interfaces, Collections Framework, disponibiliza diversas
implementações robustas dessas interfaces fornecendo uma base de
partida quase completa para a aplicação de coleções sem necessidade
de criação de raiz de coleções próprias, porém caso o programador
assim o desejar poderá customizar suas próprias implantações de
coleções tendo como base as interfaces definidas pelo Framework;
alias, essa é a grande vantagem do uso de interfaces.
As implementações mais comuns das interfaces do Collections
Framework que serão tratados ao longo das próximas unidades
temáticas estão apresentadas na figura abaixo.

Figura 141: Algumas implementações de Coleções

Nas próximas unidades temáticas iremos apresentar com detalhes estas


implementações.

Sumário

Nesta unidade temática 5.1 introduzimos o Collection Framework,


apresentando a sua essência, as vantagens do seu uso e os
componentes essenciais do mesmo. Nas próximas unidades temáticas
iremos aprofundar este tema entrando em detalhes das Listas,
Conjuntos e Mapas.

Exercícios de autoavaliação

Perguntas
1. O que é Collections Framework?
2. Quais são as vantagens do Collections Framework?
3. Liste as interfaces bases do Collections Framework?
4. Quais são algumas implementações das interfaces do
Collections Framework?

212
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Respostas
1. Collections Framework é um conjunto de classes, interfaces
e algoritmos que permitem representar e manipular
estruturas de dados complexos.
2. Collections Framework foi criado para eliminar as lacunas
dos arrays. As classes do Collections Framework flexibilizam
em muito o processo de armazenamento, recuperação e
manipulação de dados com características comuns em
coleções. Além disso, a criação de aplicações de média e
grande porte fica facilitada com a possibilidade de uso da
vasta gama de coleções disponibilizadas pelo JAVA.
3. As interfaces bases do Collections Framework são:
Collection, Set, List, Queue, Deque, Map e SortedMap.
4. Algumas implementações das interfaces do Collections
Framework são: HashSet, TreeSet, ArrayList, LinkedList,
Vector e HashMap.

Exercícios para avaliação

Nos números seguintes escolha a afirmação mais correta:


1. Visto que ArrayList implementa a interface List e esta última
estende Collection, então pode se dizer com certeza que:
a) Instâncias de Collection podem ser referenciadas por
variáveis do tipo ArrayList!
b) Instâncias de ArrayList podem ser referenciadas por
variáveis do tipo Collection!
c) ArrayList e Collection definem exatamente os mesmos
métodos!
2. Porque ArrayList, Vector e LinkedList implementa a interface
List, pode se afirmar que
a) Todas estas classes possuem exatamente os mesmos
métodos;
b) Todas estas classes implementam métodos em comum;
c) Cada uma destas classes pode ser usada para referenciar
instâncias das outras.
3. Por que se recomenda o uso de Collection Framework ao
invés de arrays.
a) Porque os arrays são legados;

213
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

b) Porque Collections Framework flexibiliza o trabalho com


estruturas complexas;
c) As duas opções são verdadeiras.
4. Verdade ou falso que no topo de todas as interfaces do
Collection Framework está a interface “Collection”?
a) Verdade;
b) Falso;
c) É verdade, mas pode ser falso.
5. Quais são algumas implementações da interface Collection?
a) Set, List e Map;
b) Vector, HashSet e HashMap;
c) HashSet, Vector e LinkedList.

Respostas: 1b, 2b, 3b, 4b, 5c.

Unidade temática 5.2. As listas (List)

Introdução
As listas representam as estruturas mais simples do Collections
Framework; uma lista é definida como “Coleção de dados ordenados”
em que cada elemento ocupa uma posição definida por um índice
numérico. A base de todas as listas do Collections Framework é a
interface “List” a qual define os métodos bases de todas as listas. Nesta
unidade temática iremos abordar a essência das listas. Começaremos
por apresentar a interface List e seus métodos mais usados, mais
adiante apresentaremos algumas classes que implementam esta
interface e a aplicação das mesmas.
Ao completar esta unidade temática 5.2, você deverá ser capaz de:

▪ Compreender: a deia da estrutura de dados List;


▪ Listar: os métodos essenciais da interface List;
▪ Instanciar: e fazer uso das implementações da interface List;
Objectivos
▪ Aplicar: polimorfismo com listas tendo como base a interface
específicos List.

214
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

A interface List e seus métodos


A interface List localizada no pacote “java.util” representa a base das
listas de Collections Framework. Ela define a essência das listas através
dos métodos nela assinados.
As listas têm a particularidade de armazenar os seus elementos em
posições específicas da coleção que lembram uma fila sequencial. Em
uma lista, cada elemento ocupa uma posição (célula) identificada por
um índice numérico. O índice é sempre um número inteiro não negativo
com o “zero” representando a primeira posição da lista e “n - 1”
representando a última posição da lista (onde “n” representa a
capacidade máxima da lista).
Os métodos essências da interface List encontram-se apresentados na
tabela abaixo.

Método Propósito
int size() Retorna a quantidade de elementos
contidos na lista
boolean isEmpty() Retorna “true” se a lista não tiver
elementos ou “false” no caso
contrário.
boolean contains(Object o) Verifica se um determinado objeto
encontra-se ou não na lista. Retorna
“true” se a lista conter o objeto ou
“false” no caso contrário.
Iterator<E>iterator() Disponibiliza o iterador para a lista.
Um iterador é uma instância de
“Iterator” que permite iterar pela
lista.
Object[] toArray() Converte a lista em um array.
Retorna um array contendo todos os
elementos da lista.
boolean add(E e) Adiciona um elemento à lista. O
elemento é adicionado no fim da
lista. Este método retornará “false”
se o elemento não pode ser
adicionado a lista.
boolean remove(E e) Remove da lista a primeira
ocorrência do elemento passado
pelo parâmetro. Este método
retorna “false” se o elemento não
estiver na lista.
boolean Verifica se a lista contém todos os
containsAll(Collection<?> c) elementos contidos numa

215
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

“Collection” e retorna “true” nesse


caso.
boolean addAll(Collection<? Adiciona a lista todos os elementos
extends E> c) contidos numa lista.
boolean Remove da lista todos os elementos
removeAll(Collection<?> c) contidos na “Collection” passada
pelo parâmetro
Boolean Remove da lista todos os elementos
retainAll(Collection<?> c) não presentes na “Collection”
passada pelo parâmetro.
void clear() Remove da lista todos os seus
elementos;
boolean equals(Object o) Verifica se a lista é igual ao objeto
passado pelo parâmetro. Este
método retorna true se e somente se
o objeto passado pelo parâmetro for
também uma lista e cada elemento
desta lista for igual ao da lista a
comparar e os elementos iguais
estiverem nas mesmas posições.
E get(int index) Retorna o elemento (da lista) na
posição especificada pelo “index”.
Este método irá rebentar a exceção
“IndexOutOfBoundsException” se o
“index” for negativo ou se for
superior ou igual ao tamanho
corrente da lista.
E set(int index, E element) Substitui o elemento na posição
“index” pelo elemento passado pelo
parâmetro. Este método retorna o
elemento substituído.
void add(int index, E element) Adiciona um elemento a uma
posição específica. Todos os
elementos a frente da posição
inserida serão afastados uma casa
para frente.
E remove(int index) Remove o elemento na posição
indicada pelo “index”. Este método
retorna o elemento removido. A lista
será redimensionada após a
remoção, afastando todos os
elementos afrente deste elemento
uma casa para trás. Este método irá
rebentar a exceção
“IndexOutOfBoundsException” se o

216
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

“index” for negativo ou se for


superior ou igual ao tamanho
corrente da lista.
int indexOf(Object o) Retorna a posição [na lista] do objeto
passado pelo parâmetro ou -1 se o
objeto não estiver na lista.

Implementações da interface List


As implementações mais famosas da interface List são as classes
ArrayList, Vector e LinkedList. Do ponto de vista de implementação,
ArrayList e Vector são muito semelhantes, tendo como base Array para
armazenar os seus elementos. Vector é considerado classe legada;
trata-se de uma adaptação da classe Vector que originalmente não
implementava a interface List. Vector é relativamente mais lenta que
ArrayList visto que a primeira usa métodos sincronizados
(synchronized)8. Outra diferença entre estas duas classes consiste no
fato de que quando o array associado estiver completamente lotado, o
ArrayList redimensiona o mesmo em 50% do tamanho corrente ao
passo que Vector duplica o seu tamanho corrente.
A implementação da classe LinkedList usa uma lógica totalmente
diferente das duas classes descritas no parágrafo anterior. LinkedList
(ou lista encadeada) usa uma estrutura própria chamada “Node” que
permite que cada elemento da lista esteja ligado ao seu elemento
anterior e posterior. Neste tipo de lista o posicionamento do elemento
é irrelevante!

Do ponto de vista de aplicação, todas as listas apresentam muitas


semelhanças uma vez que todas elas têm como base a interface “List”
é por isso que uma lista pode facilmente ser substituída pela outra. Na
hora de escolher qual das listas usar irá pesar a questão de
“performance”. A estrutura LinkedList apresenta maior desempenho
nas inserções e na iteração ao longo da lista da ponta-a-ponta. O
desempenho é baixo quando se pretende aceder a posições específicas
por meio de índices. Já ArrayList e Vector são mais eficazes neste tipo
de acesso. Outra questão relevante tem a ver com acesso sincronizado.

8
Um método “synchronized” é um método que garante acesso concorrente. Isto é,
em uma aplicação com múltiplas threads tentando invocar o mesmo método [ao
mesmo tempo] apenas uma thread terá acesso ao método a cada instante. As outras
threads só terão acesso ao método após que a thread corrente tiver liberado o
método. É uma técnica que garante que os dados são acedidos e modificados de forma
segura.

217
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Conforme referido antes, Vector garante acesso sincronizado à lista,


pelo que em uma aplicação com múltiplas threads (multi-thread)
acedendo a lista de forma concorrente, é indicado o uso deste tipo de
lista(Vector).

Instanciação de listas
O código na figura seguinte apresenta alguns exemplos instanciação de
listas. Mais baixo apresentam-se algumas notas importantes sobre cada
ponto em destaque no código.

Figura 142: Instanciação de listas


Neste exemplo instancia-se as três implementações List abordadas no
subtópico anterior.
Nos pontos 1, 4 e 7 declara-se variáveis respetivamente do tipo
ArrayList, Vector e LinkedList. Note que estas classes são classes
genéricas pelo que levam parâmetro de entrada. Isso significa que cada
uma destas listas irá aceitar apenas elementos do tipo específico.

218
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

No ponto 2 e 3 instancia-se o ArrayList, primeiro usando o construtor


sem parâmetro, segundo usando o construtor que leva a dimensão
inicial da lista. O primeiro irá criar uma lista com capacidade inicial de
10 elementos; o segundo irá criar uma lista com capacidade inicial de
80 elementos.
Nos pontos 5 e 6, instancia-se o Vector, usando o primeiro construtor
que leva como parâmetro a dimensão inicial da lista (neste caso 100) e
depois usando o construtor sem parâmetro o qual permite criar uma
lista com dimensão inicial de 10.

Nas linhas 8 e 9 instancia-se o LinkedList primeiro com o construtor sem


parâmetro, depois com o construtor que recebe uma Collection como
parâmetro. Este último construtor cria uma lista carregada inicialmente
com os elementos contidos na Collection.

Manipulação de listas
A manipulação de listas é feita essencialmente pelos métodos, add e
get. O primeiro permite adicionar um elemento à lista e o segundo
permite obter um elemento em uma determinada célula. Outros
métodos que usualmente são usados é o método “size” e “set”. O
método “size” fornece a quantidade corrente de elementos na lista e o
método “set” permite substituir o elemento numa determinada posição
da lista. O exemplo abaixo usa a classe ArrayList para armazenar e
recuperar instâncias de Pessoa (apresentada na unidade temática 3.5).
Note que o mesmo exemplo poderia ter sido implementado aplicado a
classe Vector ou LinkedList sem grandes modificações no código.

219
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 143: Manipulação de listas


Neste exemplo usa-se uma instância de ArrayList para armazenar e
manipular pessoas.

No ponto 1, recorrendo ao método “add” adiciona-se uma instância de


Pessoa à lista “pessoas”; note que esta instância é criada e
imediatamente passada ao método em causa.
No ponto 2 adicionamos à lista instância de Pessoa referenciada pela
variável “p” e no ponto 3 novamente adicionamos uma instância de
Pessoa criada no mesmo ponto.
No ponto 4 recuperamos o elemento na posição zero; portanto o
primeiro elemento da lista este elemento é armazenado na variável
“pessoa”.
No ponto 5 manipulamos o elemento na posição 1 da lista; neste caso,
invocamos sobre este elemento o método “printConta”.
No ponto 6 atualizamos o elemento na posição 2 [da lista] recorrendo
ao método “set”.

220
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Iteração em listas
A iteração em listas é o mecanismo pelo qual os programas percorrem
a lista da ponta-a-ponta. Normalmente, a cada iteração o programa
executa algumas operações sobre a lista, estas operações vão desde
simples operações de visualização da informação do elemento corrente
até operações complexas como por exemplo as relacionadas com
ordenação da lista.
A iteração em uma lista é feita usualmente recorrendo ao ciclo “for” ou
recorrendo ao iterador da lista (Iterator). No exemplo seguinte, ilustra-
se diferentes formas de iterar sobre uma lista, no caso, usa-se uma lista
de tipo LinkedList.

Figura 144: Iteração em listas


Este exemplo apresenta as 3 formas mais comuns de iterar sobre uma
lista.

221
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

O programa começa por criar e popular a lista com 100 números


aleatórios [ponto 1].
De seguida, no ponto 2, itera-se sobre a lista usando o ciclo “for”. Note
o uso da condição “i < numeros.size()” como condição de paragem do
ciclo! A cada iteração recupera-se o elemento na posição corrente
através da invocação “números.get(i)”.
No ponto 3 temos outra forma de iteração em lista. Note que aqui usa-
se um ciclo “for” que percorre diretamente a lista guardando o
elemento corrente na variável “numero”. Aqui não fazemos uso do
método “get”. Este tipo de iteração é conhecido como “for-each” (para
cada elemento)

A última forma de iterar sobre uma lista é por meio de um iterador


(Iterator). Este iterador é obtido invocando o método “iterator” sobre a
lista. A iteração poderá ser feita recorrendo ao ciclo “while” usando
como condição de paragem o retorno do método “hasNext()” que
retorna false quando se atinge o fim da lista ou se a lista for vazia. A
cada iteração usa-se o método do iterador “next” que disponibiliza o
elemento corrente.

Ordenação de listas
Em programação a ordenação de listas é uma operação por vezes
imprescindível, como por exemplo quando se pretende ordenar a lista
de estudantes de uma turma com base no nome ou ordenar os
funcionários de uma instituição com base no seu salário. Collections
Framework disponibiliza alguns mecanismos para a ordenação de listas
e no âmbito deste manual apenas iremos tratar do processo de
ordenação recorrendo ao método “sort” da classe Collections.

O método “Collections.sort()” permite ordenar qualquer que seja a lista


de subtipo de List bastando que seus elementos implementem a
interface Comparable. No exemplo seguinte ilustramos um programa
que ordena uma lista de pessoas em ordem crescente do código. Note
que a classe Pessoa precisa implementar a interface “Comparable” e o
único método definido nesta interface, o método “compareTo”.

222
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 145: A classe Pessoa como Comparable

Ao implementar a interface “Comparable” a classe Pessoa torna-se


comparável, isto é, suas instâncias podem ser comparadas entre si. O
método “compareTo” em destaque no ponto 2 é o único método
definido pela interface “Comparable” e ele determina qual dos objetos
é maior que o outro entre o objeto “this” e o objeto recebido pelo
parâmetro. Este método pode retornar três tipos de valores,
nomeadamente (1) um número inteiro positivo, indicando que o objeto
“this” é maior que o objeto recebido pelo parâmetro (2) um número
inteiro negativo, indicando que o objeto “this” é menor que o objeto
recebido pelo parâmetro ou (3) zero, indicando que o objeto “this” é
igual ao objeto recebido pelo parâmetro. A interface “Comparable” é
uma interface genérica e o parâmetro recebido na sua definição deve
coincidir com o tipo passado para o método “compareTo”

223
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

A seguir apresenta-se a aplicação “AppOrdenacao” que permite


ordenar uma lista de Pessoa. Neste exemplo usa-se a lista do tipo
Vector.

Figura 146: Ordenação de Lista


Neste exemplo primeiro criamos uma lista do tipo Vector (Ponto 1); de
seguida povoamos esta lista com instancias desordenadas de Pessoa.
No ponto 3, ordenamos a lista usando o método “sort” da classe
Collections. No ponto 4, imprimimos a lista ordenada na tela.

Polimorfismo com listas


O polimorfismo é um poderoso conceito que fornece uma base para a
abstração. Conforme tratado no tema II, recorrendo ao polimorfismo e
a abstração consegue-se projetar soluções abrangentes com menos
esforço. O polimorfismo aparece com frequência quando se projeta
soluções com classes da Collections Framework. É estritamente
recomendável que qualquer referência seja feita usando as interfaces
de Collection Framework no lugar de classes específicas. No caso de
listas, a recomendação é que seja usada a interface List.
No exemplo seguinte apresentamos uma situação em que faz o uso de
polimorfismo com listas.

224
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 147: Polimorfismo com listas.

Neste exemplo ilustra-se o uso de polimorfismo com listas. Note que no


ponto 1 declara-se três variáveis do tipo List, mas cada uma delas
recebe um tipo de lista diferente. A primeira, referencia uma instância
de LinkedList, a segunda, ArrayList e a terceira referência uma instância
de Vector. Note ainda que no ponto 2, invoca-se o método
“ordenarLista”. Trata-se de um método que aceita qualquer referência
de List. Este método foi definido no ponto 3. Por ser um método que
recebe qualquer referência de List, para este método podemos passar
qualquer instância de cada uma das classes que implementam esta
interface.
O uso da interface List para referenciar instâncias de subtipos desta
interface, para além de aumentar a
225
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

abrangência dos métodos flexibiliza o processo de migração de uma


lista para outra. Para melhor entender esta declaração imagine uma
aplicação que foi concebida para armazenar suas entidades em uma
lista do tipo ArrayList. Sem usar o polimorfismo, tal aplicação terá
certamente a referência ao ArrayList em vários trechos da mesma. Se
no futuro o programador decidir, por alguma razão (performance, por
exemplo) migrar a sua aplicação para usar LinkedList, terá de percorrer
a aplicação e modificar a ocorrência de ArrayList por LinkedList. Este
trabalho seria simplificado se ao invés de “espalhar” referências a
ArrayList, o programador tivesse usado referência a List. É ainda
aconselhável usar a interface List para fazer referência a instâncias de
suas implementações para garantir o uso padronizado das listas
evitando fazer referência a métodos próprios das implementações ao
invés dos métodos padronizados.

Sumário
Nesta unidade temática 5.2 abordamos as listas da Collections
Framework. Começamos por definir lista e apresentar a essência da
interface List; trata-se da interface base para todas as listas
disponibilizadas pelo java. De seguida apresentamos as
implementações mais famosas desta interface, nomeadamente:
ArrayList, Vector e LinkedList. Abordamos as diferenças fundamentais
destas implementações bem como a indicação para o uso de cada uma
delas. Foram apresentados alguns exemplos de aplicação destes tipos
de listas. Abordamos ainda a questão de ordenação de listas para
finalizar com polimorfismo com listas.

Exercícios de autoavaliação
Perguntas
1. Descreva a essência de lista;
2. Quais são os métodos mais comuns da interface List usados
para manipular as listas e para que serve cada um desses
métodos?
3. Lista as diferenças essenciais das três implementações mais
comuns da interface List.
4. Modifique o programa apresentado no subtópico
“Ordenação de Listas” para que ordene as pessoas usando o
nome.
5. Modifique o programa criado no exercício anterior para que
liste as pessoas em ordem decrescente de idades.
6. Modifique o programa apresentado no subtópico
“Ordenação de Listas” para que use um iterador para a
listagem de pessoas.

226
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Respostas
1. As listas têm a particularidade de armazenar os seus
elementos em posições específicas da coleção que lembram
uma fila sequencial. Em uma lista, cada elemento ocupa uma
posição (célula) identificada por um índice numérico. O
índice é sempre um número inteiro não negativo com o
“zero” representando a primeira posição da lista e “n - 1”
representando a última posição da lista (onde “n”
representa a capacidade máxima da lista).
2. Os métodos mais comuns da interface List são: (1) add: que
permite adicionar um elemento a lista (2) get: recupera um
elemento numa dada posição da lista (3) size: retorna o
tamanho da lista e (4) set: actualiza um elemento específico
na lista.
3. Do ponto de vista de implementação, ArrayList e Vector são
muito semelhantes, tendo como base Array para armazenar
os seus elementos. Vector é considerado classe legada;
trata-se de uma adaptação da classe Vector que
originalmente não implementava a interface List. Vector é
relativamente mais lenta que ArrayList visto que a primeira
usa métodos sincronizados. Outra diferença entre estas
duas classes consiste no fato de que quando o array
associado estiver completamente lotado, o ArrayList
redimensiona o mesmo em 50% do tamanho corrente ao
passo que Vector duplica o seu tamanho corrente.

A implementação da classe LinkedList usa uma lógica


totalmente diferente de ArrayList e Vector. LinkedList (ou
lista encadeada) usa uma estrutura própria chamada “Node”
que permite que cada elemento da lista esteja ligado ao seu
elemento anterior e posterior. Neste tipo de lista o
posicionamento do elemento é irrelevante!
4. Para alterar a forma de ordenação basta mudar o método
“compareTo”; neste caso modificamos este método para
fazer a comparação com base no nome do indivíduo.

227
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

5. Novamente, precisamos modificar o método “compareTo”.

6. Resolução

228
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Exercícios para avaliação


Das declarações seguintes, assinale aquelas que são verdadeiras:
1. As listas do tipo LinkedList garantem maior performance.
2. Uma instância de ArrayList pode ser referenciada por
variáveis do tipo List;
3. Uma instância de Vector pode ser referenciada por variáveis
do tipo ArrayList;
4. Qualquer que seja a lista (que implemente a interface List)
pode ser ordenada recorrendo ao método “sort” da classe
“Collections”;
5. Em aplicações com listas, recomenda-se o uso da interface
List para fazer referências a instâncias de subtipos desta
interface.
6. Em uma lista de Pessoa, pode se adicionar instâncias de
Trabalhador, se trabalhador for subclasse de Pessoa.
7. Uma lista de Trabalhador pode ser referenciada por uma
variável do tipo lista de Pessoa se Pessoa for superclasse de
Trabalhador.

229
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

8. Qualquer lista que implementa a interface List pode ser


substituída por uma outra que implemente a mesma
interface?
9. Para que uma lista que implemente a interface “List” seja
ordenável pelo método “Collections.sort()” a mesma deve
implementar a interface Comparable;
10. Algumas implementações da interface “List” de Collection
Framework usam array na sua estrutura interna.
Resposta: 1-F, 2-V, 3-F, 4-F, 5-V, 6-V, 7-F, 8-F, 9-F, 10-V.

Unidade Temática 5.3. Os Conjuntos (Set)

Introdução
Os conjuntos constituem estrutura de dados bastante usadas em
aplicações de média e grande porte. Os conjuntos em java aproximam-
se aos conjuntos matemáticos e diferenciam-se fundamentalmente das
listas pelo facto de não aceitarem elementos duplicados e os seus
elementos não serem referenciados índices. À semelhança das listas, os
conjuntos têm como base uma interface, a interface “Set” e o java
disponibiliza algumas implementações desta interface das quais iremos
abordar a classe HashSet.
Ao completar esta unidade temática 5.3, você deverá ser capaz de:

▪ Compreender: a estrutura de dados Set;


▪ Listar: os métodos essenciais da interface java.util.Set;
▪ Instanciar: e fazer uso das implementações da interface
Objectivos
java.util.Set;
específicos

A interface Set e seus métodos


Um conjunto representa uma coleção de dados não sequenciais,
diferentemente da lista que representa uma coleção sequencial. Os
conjuntos, em java, abstraem os conjuntos matemáticos e como o seu
nome sugere, comumente são usados para armazenar conjuntos de
dados tais como, as disciplinas de um estudante. Os conjuntos não
aceitam duplicação de elementos. Dois elementos são considerados
iguais se a comparação usando o método “equals” retorna “true” ao
mesmo tempo que os mesmos partilham o mesmo “hashCode”
disponibilizado pelo método “hashCode”.
A tabela abaixo apresenta os métodos mais comuns da interface “Set”

230
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Método Propósito
int size() Retorna a quantidade de elementos
contidos no conjunto.
boolean isEmpty() Retorna “true” se o conjunto não
tiver elementos ou “false” no caso
contrário.
boolean contains(Object o) Verifica se um determinado objeto
encontra-se ou não no conjunto.
Retorna “true” se a lista conter o
objeto ou “false” no caso contrário.
Iterator<E>iterator() Disponibiliza o iterador para o
conjunto. Um iterador é uma
instância de “Iterator” que permite
iterar pelo conjunto.
Object[] toArray() Converte o conjunto em um array.
Retorna um array contendo todos os
elementos do conjunto;
boolean add(E e) Adiciona um elemento ao conjunto
se este ainda não estiver na lista.
Este método retornará “false” se o
elemento não pode ser adicionado
ao conjunto. Note que para que dois
elementos sejam considerados
“mesmo elemento” a comparação
entre os dois usando o método
“equals” deve retornar “true” e os
mesmos devem retornar o mesmo
valor a chamada do método
“hashCode”.
boolean remove(E e) Remove do conjunto o elemento
passado pelo parâmetro. Este
método retorna “false” se o
elemento não estiver no conjunto.
boolean Verifica se o conjunto contém todos
containsAll(Collection<?> c) os elementos contidos numa
“Collection” e retorna “true” nesse
caso.
boolean addAll(Collection<? Adiciona ao conjunto todos os
extends E> c) elementos contidos numa Collection.
boolean Remove do conjunto todos os
removeAll(Collection<?> c) elementos contidos na “Collection”
passada pelo parâmetro

231
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Boolean Remove do conjunto todos os


retainAll(Collection<?> c) elementos não presentes na
“Collection” passada pelo parâmetro.
void clear() Remove da conjunto todos os seus
elementos;
boolean equals(Object o) Verifica se a conjunto é igual ao
objeto passado pelo parâmetro. Este
método retorna “true” se e somente
se o objeto passado pelo parâmetro
for também um conjunto, e ambos
tenham mesma quantidade de
elementos e cada elemento deste
conjunto for igual ao do conjunto a
comparar.

Implementações da interface Set


À semelhança de listas, o java disponibiliza algumas implementações
da interface Set dos quais se destaca: HashSet e TreeSet. Neste
manual iremos apenas abordar a classe HashSet.

A classe HashSet usa um mapa9 (HashMap) para armazenar os


elementos do conjunto e segue de perto a lógica definida pela
interface Set. Um HashSet, tal como definido na interface Set, não
permite duplicações, isto é, não permite que o mesmo elemento seja
adicionado no conjunto mais de uma vez! Considera-se que dois
elementos são o mesmo, se forem iguais pelo método “equals” e se a
invocação do método “hashCode” sobre os dois elementos tiver
mesmo retorno. A iteração pelo HashSet é feita sempre usando um
“Iterator” e não está garantido que múltiplas iterações sejam feitas na
mesma sequência.

Criação, Manipulação e Iteração em HashSet


O HashSet pode ser iniciado recorrendo a um dos seus construtores. O
construtor mais comum é o construtor que não leva parâmetro. A
manipulação do HashSet é feita essencialmente usando o método
“add”, para incluir elementos no conjunto e o “iterador” para iterar
pelos elementos contidos no conjunto. O exemplo seguinte ilustra a
aplicação do HashSet; note que aqui, o HashSet é referenciado
recorrendo a interface Set! Lembre-se, esta é uma boa prática quando
lidamos com instâncias do Collections Framework.

9
Mais adiante será apresentada a collection “Map” e a usa implementação “HashMap”.

232
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 148: Criação e manipulação de HashSet

O código apresentado na figura anterior ilustra o processo de uso de um


HashSet. No ponto 1 cria-se o HashSet (do tipo pessoa) o qual é
associado a variável “set” do tipo “Set”. De seguida, no ponto 3, popula-
se o conjunto recorrendo ao método “add”. No ponto 4, recupera-se o
iterador do conjunto e, finalmente no ponto 5, itera-se sobre o
“iterador” usando o ciclo “while”. No ponto 6 itera-se sobre o conjunto
usando o ciclo “for-each”

Sumário
Nesta unidade temática 5.3 apresentamos a essência de conjuntos.
Começamos por apresentar a interface Set que descreve as habilidades
comuns a todos os conjuntos do Collections Framework. De seguida
fizemos uma breve revisita a classe HashSet que é uma das

233
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

implementações mais comuns da interface Set.

Exercícios de autoavaliação
Perguntas
1. Quais são as características que fundamentalmente diferenciam
um conjunto de listas?
2. Qual é a interface base de conjuntos do Collection Framework?
3. Mencione alguns métodos essências dos conjuntos do
Collections Framework.
4. Explica como faria para localizar um elemento de um conjunto.
5. Elabore um programa que permite armazenar indivíduos em um
conjunto do tipo HashSet e de seguida localize um individuo
específico dado o seu código.
Notas: (1) use a classe Pessoa [apresentada na unidade temática
5.2] como descritor do individuo (2) os dados necessários devem
ser obtidos pelo teclado (3) a quantidade de indivíduos é
indefinida. (4)
Respostas:
1. Enquanto uma lista que representa uma coleção sequencial de
dados, o conjunto representa uma coleção de dados não
sequenciais. As listas podem conter elementos duplicados, ao
passo que os conjuntos, não.
2. A interface base dos conjuntos é Set.
3. Os métodos essenciais dos conjuntos do Collections Framework
são definidos na interface Set, são eles: add que permite
adicionar um elemento ao conjunto; iterator que disponibiliza o
iterador do conjunto; remove que permite remover um elemento
da lista.
4. Para identificar o elemento do conjunto é necessário iterar sobre
este; a iteração pode ser feita recorrendo à iteração pelo respetivo
iterador ou recorrendo ao ciclo “for-each” sobre o conjunto. A
cada iteração seria necessário se o elemento corrente equivale ou
não ao que se pretende identificar.
5. Resolução

234
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 149: Resolução exercício 5

Exercícios para avaliação


Assinale as afirmações verdadeiras:

235
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

1. A única forma de recuperar elementos em um “HashSet” é


usando o iterador ou um for-each.
2. Em todos os casos, a invocação do método “iterator” sobre
um “Set” disponibiliza os elementos do conjunto na mesma
ordem.
3. Não é possível adicionar dois elementos iguais em um “Set”.
4. A recuperação de elementos em um “Set” é feita da mesma
forma que em uma “List”.
5. Não é possível recuperar um elemento específico de um
“Set”.
6. Os “Set” são indicados para conjuntos matemáticos.
7. Os conjuntos e listas do Collection Framework tem a
particularidade de implementar a interface “Collection”.
8. Todas as implementações de “Set” tem exatamente os
mesmos métodos e estes são definidos na interface “Set”.
9. A invocação do método “add” sobre qualquer referência de
“Set” inclui um elemento em um conjunto.
10. Os elementos em um HashSet não possuem uma ordem.
Respostas: 1-V, 2-F, 3-V. 4-F, 5-F, 6-V, 7-V, 8-F, 9-F, 10-V.

236
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Unidade temática 5.4. Os mapas (Map)

Introdução
Um mapa é uma estrutura que organiza os dados aos pares; cada par é
constituído por uma chave e o valor correspondente. Os mapas são
largamente usados em aplicações de grande porte incluindo em APIs e
frameworks de desenvolvimento. Nesta unidade temática 5.4 vamos
apresentar a essência dos mapas.
Ao completar esta unidade temática 5.4, você deverá ser capaz de:

▪ Compreender: a estrutura de dados Map;


▪ Listar: os métodos essenciais da interface java.util.Map;
▪ Instanciar: e fazer uso das implementações da interface
Objectivos
java.util.Map;
específicos

A interface Map e seus métodos


Um mapa é uma estrutura de dados que faz mapeamento de chaves aos
seus correspondentes valores, portanto, cada elemento em um mapa é
um par de “chave” e “valor”. Em um mapa, cada “chave” fica associada
a um e único valor. Os mapas não permitem duplicação. Os mapas
disponibilizados pelo java têm a sua lógica definida pela interface
“Map” do pacote “java.util”; trata-se de uma interface genérica que
define dois parâmetros, um representando a chave e outro
representando o valor (Map<Key, Value>). Na tabela seguinte estão
listados os métodos essências da interface “Map”.
Método Propósito
void clear() Remove do mapa todos os seus
elementos
boolean containsKey(Object Verifica se o mapa contêm a chave
chave) passada pelo parâmetro.

boolean containsValue(Object Verifica se o mapa contêm o valor


valor) passado pelo parâmetro.

Set<Map.Entry<K,V>> Retorna um conjunto de elementos


entrySet() (chave-valor) contidos no mapa.

V getValue(Object chave) Retorna o valor associado a chave


passada pelo parâmetro.

237
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

V put(K chave, V valor) Inclui no mapa o par “chave” –


“valor”. Se o mapa já tiver o par em
causa, o “valor” será atualizado. Este
método retorna o “valor” que
previamente estava associado à
“chave”.
V remove(Object chave) Remove do mapa o par associado a
“chave”. Este método retorna o
“valor” associado a “chave”.
int size() Retorna a quantidade de elementos
contidos no mapa.
boolean isEmpty() Retorna “true” se o mapa não tiver
elementos ou “false” no caso
contrário.

Implementações da interface Map


O java disponibiliza pelo menos quatro implementações da interface
“Map”, a saber “HashMap”, “HashTable”, “TreeMap” e
“LinkedHashMap”. Neste manual será apenas abordada a
implementação “HashMap” por ser a mais conhecida e mais usada em
aplicações.
A classe “HashMap” é uma implementação da interface “Map” que
providencia todas as operações sobre o mapa. Esta implementação
permite chaves e valores nulos. Esta implementação não é sincronizada
(“synchronized”) pelo que o seu uso em aplicações concorrentes poderá
resultar em inconsistência de dados. A versão “synchronized” de mapas
é disponibilizada pela classe “HashTable”.

Aplicação com Mapas


Neste tópico vamos apresentar a essência do uso de mapas em
aplicações. Começaremos por apresentar exemplo de instanciação e
povoamento do mapa bem como recuperação de elementos. Mais
adiante iremos apresentar a iteração pelo mapa.

238
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 150: Aplicação com Mapas

Neste exemplo, ponto 1, instancia-se o “HashMap”. Note que esta


instância fica associada a variável “pessoas” do tipo “Map” ao invés de
uma variável do tipo “HashMap”. Esta é uma boa prática de
programação, usar as interfaces para fazer referência às instâncias ao
invés de implementações concretas. Aqui definimos um mapa com
chaves do tipo “Integer” e valores do tipo “Pessoa”. Note que a chave e
o valor poderão ser de qualquer tipo não primitivo.
No ponto 2, colocamos no mapa três elementos usando o método
“put”. Cada elemento é um par “chave-valor” em que a chave é um
Integer e o valor é uma instância de Pessoa.
No ponto 3, usando o método “get” recuperamos o valor associado a
chave “1234” e de seguida mandamos visualizar os seus dados.

Iteração em um Mapa
A interação em mapas é feita recorrendo ao método “entrySet”. Este
método retorna um conjunto contendo todos os elementos contidos na
lista no formato “Map.Entry<K,V>”. Um “Map.Entry” é um objeto que
permite acesso rápido a “chave” e o correspondente “valor” de um
elemento do mapa. No exemplo seguinte itera-se sobre os elementos
do mapa apresentado no exemplo do tópico anterior.

239
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Figura 151: Iterando sobre um mapa

Sumário
Nesta unidade temática 5.4 abordamos a essência dos mapas. Foi
apresentada a interface “Map” do pacote “java.util” os seus métodos
essências. Finalizamos com exemplos que ilustram o uso dos mapas.
Nestes exemplos aplicamos uma das implementações da interface
“Map”, a classe “HashMap”.

Exercícios de autoavaliação
Perguntas
1. Descreva a estrutura de dados mapa;
2. Quais são algumas implementações da interface “Map” do pacote
“java.util”?
3. Qual é a diferença principal entre mapas e conjuntos do
Collection Framework?
4. Qual é a diferença principal entre mapas e listas?
5. Modifique os programas apresentados nesta unidade temática 5.4
de modo a usarem um mapa cujas as chaves são do tipo String.
Respostas:
1. Mapa é uma estrutura de dados que organiza os dados aos pares.
Cada par é composto por uma “chave” e um “valor”. A chave é

240
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

usada para referenciar o valor associado.


2. As seguintes classes são exemplos de implementação da interface
“Map”: “HashMap”, “HashTable”, “TreeMap” e
“LinkedHashMap”
3. Os mapas relacionam cada um dos seus elementos com uma
chave, ao passo que os conjuntos, não.
4. Os mapas relacionam cada um dos seus elementos com uma
chave de tipo objeto, ao passo que as listas relacionam os
elementos a uma chave numérica.
5. Resolução

Exercícios para avaliação


Assinale com “V” as afirmações verdadeiras e “F” as falsas.
1. A chamada ao método “put” sobre um “Map” retorna
sempre um objeto.

241
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

2. A chamada ao método “put” sobre um “HashMap” resultará


numa “Exception” se um dos parâmetros for “null”.
3. Um “Map” não deve permitir chaves duplicadas.
4. A iteração sobre um “Map” pode ser conseguida por meio
de um “Iterator”.
5. A iteração sobre um “Map” pode ser conseguida por meio
de um “entrySet”.
6. A chamada ao método “put” sobre qualquer referência de
Map inclui um objeto em um mapa.
7. Todas as implementações da interface “Map” do Collection
Framework tem métodos em comum métodos.
8. Todas as implementações da interface “Map” do Collection
Framework tem exatamente mesmos métodos.
9. Usando mapas do Collection FrameWork é possível
recuperar um elemento específico por meio de um método
disponibilizado pelos mapas.
10. A invocação do método “put” sobre um mapa retorna
sempre um objeto.

Respostas: 1-F, 2-F, 3-V, 4-F, 5-V, 6-F, 7-V, 8-F, 9-V, 10-F.

242
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Exercícios do tema

Exercícios de autoavaliação
Perguntas
1. Fale do processo de ordenação de listas.
2. Por que é recomendado o uso da interface List para
referenciar instâncias de subtipos de List?
3. Fale sobre os conjuntos do Collections Framework;
4. Em que circunstâncias se indica o uso de conjuntos?
5. Elabore um programa que permite criar e armazenar em um
Map, instâncias de Pessoa com base em dados lidos pelo
teclado. De seguida, o programa deverá recuperar do mapa
uma pessoa específica dado o seu código e visualizar tal
pessoa. Para gerar as instâncias de pessoa use o descritor de
Pessoa apresentando na unidade temática 5.2.
Respostas
1. A ordenação de listas é conseguida recorrendo ao método
Collections.sort. Este método permite ordenar qualquer lista
que implemente a interface “List”. O requisito único para
que tal lista possa ser ordenada é necessário que o tipo de
parâmetro a ela associada seja um “Comparable”.
2. É recomendável usar a interface para fazer referências à
listas para aumentar a abrangência dos métodos e
flexibilizar a migração de uma lista para outra.
3. Os conjuntos do Collections Framework fazem alusão aos
conjuntos matemáticos; eles têm como base a interface Set.
Os conjuntos não permitem elementos duplicados.
4. O uso de conjuntos é indicado para situações em que se
pretende trabalhar com elementos únicos.
5. Resolução

243
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

Exercícios de avaliação
1. Se uma classe implementa a interface “Comparable” significa
que,
a) Suas instâncias poderão ser comparadas com qualquer
outra instância “comparável”;
244
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

b) Qualquer de suas instâncias pode invocar o método


“compareTo” definido na interface;
c) As duas opções anteriores estão corretas.
2. Qual é o requisito para que uma “List” possa ser ordenada pelo
método “Collections.sort(List<T> list)”?
a) Tal lista deve ser ordenável;
b) O tipo correspondente ao parâmetro T deve ser
comparável;
c) Cada um dos seus elementos deve ser comparável.
3. Por que se recomenda usar a interface “List” para fazer
referência às listas do Collection Framework?
a) Para garantir maior transparência no código;
b) Para facilitar a migração de uma lista para outra, caso se
faça necessário;
c) As duas opções anteriores estão erradas.
4. Por que se recomenda usar a interface “List” para fazer
referência às listas do Collection Framework?
a) Para garantir maior transparência no código;
b) Para tornar o uso de classes e métodos mais abrangente;
c) As duas opções anteriores estão erradas.
5. Apesar de as listas de Collection Framework serem sofisticadas
que os arrays, estas usam arrays na sua estrutura interna;
a) Sim, todas;
b) Sim, algumas;
c) Não, nenhuma.
6. É possível ordenar um conjunto de Collection Framework?
a) Não, não faz sentido;
b) Sim;
c) Talvez.
7. Em Collection Framework, qual destas afirmações é verdadeira?
a) O primeiro elemento de uma List fica na posição zero;
b) O primeiro elemento de um Set fica na posição zero;
c) As duas opções estão corretas.
8. Das instruções abaixo qual delas é mais recomendável?

245
ISCED - CURSO: Gestão de Sistemas de Informação; Ano: 40 Disciplina/Módulo: Programação Avançada em Java

a) A primeira;
b) A segunda;
c) Ambas.
9. É possível recuperar um elemento específico de um Set de
Collection Framework?
a) Sim, usando o método “get”;
b) Sim, iterando sobre o iterator associado;
c) Não é possível.
10. Em Collection Framework qual é o perigo de coleções não
“synchronized”?
a) Inconsistência de dados;
b) Insegurança de dados;
c) Confusão nos dados.
Respostas: 1b, 2b, 3b, 4b, 5b, 7a, 8a, 9b, 10a.

Referências Bibliográficas

Caelum. Java e Orientação a Objetos. Consultado em setembro de


2021. Disponível em https://www.caelum.com.br/apostila-java-
orientacao-objetos
Oracle. Collections. Consultado em setembro de 2021. Disponível em
http://docs.oracle.com/javase/tutorial/collections/index.html.
Nanyang Technological University. The Java Collection Framework.
Consultado em setembro de 2021. Disponível em
https://www3.ntu.edu.sg/home/ehchua/programming/java/J5c_Colle
ction.html.
Oracle. Collections. Consultado em setembro de 2021. Disponível em
https://docs.oracle.com/javase/tutorial/extra/generics/index.

246
247

Você também pode gostar