Sebenta de Java-Caps1a4
Sebenta de Java-Caps1a4
Java
Engenharia Informática
5 de outubro de 2023
Conteúdo
1 Introdução 5
1.1 Organização do Documento . . . . . . . . . . . . . . . . . . . 6
4 Classes e Objetos 24
4.1 Classe e suas instâncias . . . . . . . . . . . . . . . . . . . . . 24
4.2 Atributos e métodos de instância . . . . . . . . . . . . . . . . 26
4.2.1 Acessibilidade de atributos e métodos . . . . . . . . . 26
4.2.2 A referência this . . . . . . . . . . . . . . . . . . . . . 27
2
CONTEÚDO
5 Herança 36
5.1 Herança . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5.2 Sobreposição de Operadores/métodos . . . . . . . . . . . . . 40
5.3 A referência super . . . . . . . . . . . . . . . . . . . . . . . . 40
5.4 Polimorfismo . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
5.5 Sumário . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
5.6 Exercı́cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
5.6.1 Exercı́cio 1 . . . . . . . . . . . . . . . . . . . . . . . . 43
7 Coleções de Objetos 51
7.1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
7.2 Tipos de coleção . . . . . . . . . . . . . . . . . . . . . . . . . 51
7.3 Tipos Genéricos . . . . . . . . . . . . . . . . . . . . . . . . . . 52
7.4 Conjuntos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
7.5 Listas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
7.6 Conjuntos Ordenados . . . . . . . . . . . . . . . . . . . . . . 55
7.7 Outras Coleções em Java . . . . . . . . . . . . . . . . . . . . . 56
7.8 Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
7.9 Sumário . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
7.10 Exercı́cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
7.10.1 Exercı́cio 1 . . . . . . . . . . . . . . . . . . . . . . . . 57
8 Associações de Objetos 58
8.1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
8.2 Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
8.2.1 HashMap . . . . . . . . . . . . . . . . . . . . . . . . . 59
8.3 Exercı́cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
8.3.1 Exercı́cio 1 . . . . . . . . . . . . . . . . . . . . . . . . 60
10 Anotações 65
11 Constructs Funcionais 66
11.1 Sumário . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
11.2 Exercı́cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
11.2.1 Exercı́cio 1 . . . . . . . . . . . . . . . . . . . . . . . . 66
12 Programação Concorrente 67
12.1 Exercı́cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
12.1.1 Exercı́cio 1 . . . . . . . . . . . . . . . . . . . . . . . . 67
13 Boas Práticas 68
13.1 Exercı́cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
13.1.1 Exercı́cio 1 . . . . . . . . . . . . . . . . . . . . . . . . 68
15 Conclusão 70
Introdução
5
CAPÍTULO 1. INTRODUÇÃO
Modelação e Programação
Orientadas por Objetos
7
CAPÍTULO 2. MODELAÇÃO E PROGRAMAÇÃO ORIENTADAS
POR OBJETOS
compiladas para a JVM faz com que possam interoperar com programas em
Java.
Sendo uma máquina virtual, a JVM corre os seus próprios processos de
gestão e otimização de memória, sendo o garbage collector o mais conhe-
cido. Este processo liberta zonas de memória não referidas por nenhuma
variável num programa. Isto liberta o programador de preocupações como a
gestão de apontadores para posições de memória e a necessidade de libertar
memória que já não usa.
O capı́tulo seguinte apresenta os principais constructs da linguagem Java.
Os capı́tulos posteriores apresentam modelação e programação orientadas
por objetos, usando UML e Java.
10
CAPÍTULO 3. INTRODUÇÃO À LINGUAGEM JAVA
int n, i=0;
float x, y, z;
char c = ’a’;
x = 5; y = 9; z = 13;
i = 2;
x = y/2;
System.out.println("x = " + x);
i = (int)(z/y);
System.out.println("i = " + i);
System.out.println("z/y = " + (z/y));
x = 4.5
i = 1
z/y = 1.4444444
c = a
n = 97
3.2.2 Array
Um Array é uma coleção indexada (sequência) de dados de um determinado
tipo. Por exemplo, as linhas de código seguintes, de um método main,
declaram um array arrInt para armazenar dez números inteiros e um array
arrCar para quinze caracteres:
arrInt[0] = 5;
arrInt[1] = 3;
arrCar[0] = ’o’;
arrCar[1] = ’l’;
arrCar[2] = ’a’;
System.out.println(arrayInt[0] + arrayInt[1]);
System.out.println(arrayCar[0] + arrayCar[1] + arrayCar[2]);
A execução do excerto anterior provocaria o seguinte output para o ecrã:
8
ola
é possı́vel, também, declarar e inicializar um array de uma só vez. A linha
seguinte cria um array de inteiros e inicializa-o com dez inteiros, estando no
ı́ndice zero o valor 1, no ı́ndice um o valor 5, e assim por diante:
int inteiros[] = {1, 5, 8, 12, 9, 34, 7, 10, 2, 8};
Um array de N posições tem ı́ndices entre 0 e N 1.
Um array é, em Java, uma classe, pelo que um objeto do tipo Array de
dados de um outro determinado tipo, encapsula o array de dados juntamente
com operações sobre esses dados. Por exemplo, inteiros.length dá-nos o
tamanho do array inteiros declarado acima.
System.out.println(nome.length());
System.out.println(nome.charAt(4));
System.out.println(nome.substring(4, 9));
System.out.println(nome.isEmpty());
System.out.println(nome.concat(" ol\’a, ol\’a!"));
O exemplo anterior, imprime o tamanho da string (número de caracteres
em nome); depois, imprime o caracter no ı́ndice 4 da String (vista como
um array de caracteres); imprime a substring de nome entre os ı́ndices 4,
inclusivé, e 9, excluindo este; imprime true ou f alse, conforme a string
nome estiver vazia ou não; e, por fim, imprime o resultado da concatenação
de nome com a string “ olá, olá!”. O resultado impresso, seria então:
Operador Significado
⇤ Multiplicação
/ Divisão
+ Adição (também usado para concatenação de Strings)
Subtração
% Resto da divisão inteira
++ Incrementar (posfix ou prefix)
Decrementar (posfix ou prefix)
”Subtração”unária (troca de sinal)
15
M
Maria
false
Ana Maria Silva ol\’a, ol\’a!
3: y = y + (x++);
4: z = z + (++x);
5: System.out.println("x = " + x);
6: System.out.println("y = " + y);
7: System.out.println("z = " + z);
8: y += 3;
9: System.out.println("y = " + y);
O output do excerto de código acima seria:
x = 3
y = 1
z = 3
y = 4
Operador Significado
== Igualdade
!= Desigualdade
< Menor que
<= Menor ou igual a
> Maior que
>= Maior ou igual a
Operador Significado
&& E lógico
|| OU lógico
! Negação lógica
x == 3
ou
y>4
(x == 3)&&(y > 4)
(x == 3)||(y > 4)
3.6.1 if
A instrução if permite a execução condicional de uma outra instrução ou
bloco de instruções. Ou seja, se uma dada condição é verdadeira, a instrução
ou bloco de i©s seguintes serão executados. No exemplo seguinte, a linha
4 será executada apenas se a condição (x > y), da linha 3, for verdadeira:
A instrução if permite ainda uma clausula else, a qual permite que uma
outra instrução ou bloco de instruções sejam executados no caso da condição
inicial ser falsa. Ou seja, na instrução seguinte, o bloco de instruções 1 será
executado se a condição cond for verdadeira, senão (i.e., se a condição for
falsa) será executado o bloco 2:
if (cond) {
// bloco 1
...
}
else {
// bloco 2
...
}
6: else {
7: System.out.println("x \’e menor que y");
8: System.out.println("x tem valor " + x);
9: }
3.6.2 switch
Por vezes precisamos de testar várias condições em sequência, sendo execu-
tado o bloco de instruções da primeira condição que for avaliada para true.
Isto pode ser feito encadeando várias instruções if...else:
1: int x=0;
2: x++;
3: if (x == 1) System.out.println("Amarelo");
4: else if (x == 2) System.out.println("Verde");
5: else if (x == 3) System.out.println("Azul");
6: else if (x == 4) System.out.println("Vermelho");
7: else if (x == 5) System.out.println("Preto");
8: else if (x == 6) System.out.println("Branco");
9: else System.out.println("Cinzento");
1: int x=0;
2: x++;
3: switch(x){
4: case 1:
5: System.out.println("Amarelo");
6: break;
7: case 2:
8: System.out.println("Verde");
9: break;
10: case 3:
11: System.out.println("Azul");
12: break;
13: case 4:
14: System.out.println("Vermelho");
15: break;
16: case 5:
17: System.out.println("Preto");
18: break;
19: case 6:
20: System.out.println("Branco");
21: break;
22: default:
23: System.out.println("Cinzento");
24: }
3.7 Ciclos
Frequentemente queremos executar um bloco de código repetidamente en-
quanto uma condição se mantém verdadeira. As instruções seguintes permitem-
nos fazer isso.
3.7.1 while
A instrução while testa uma condição inicial, e se a mesma for verdadeira,
executa o bloco de código seguinte, senão ignora esse bloco.
No exemplo seguinte,
1: int x=0;
2: while (x < 10){
3: System.out.println("Linha " + (x+1));
4: $x = x + 1;$;
5: }
Linha 1
Linha 2
Linha 3
Linha 4
Linha 5
Linha 6
Linha 7
Linha 8
Linha 9
Linha 10
1: int x=0;
2: while (x < 10){
3: System.out.println("Linha " + (++x));
5: }
1: int x=0;
2: while (x < 10){
3: System.out.println("Linha " + (x++));
5: }
o resultado em output começará com ’Linha 0’, sendo a última linha a ’Linha
9’.
1: int x=0;
2: do{
3: System.out.println("Linha " + (++x));
5: } while (x < 10);
3.7.3 for. . .
A instrução for permite duas abordagens:
3.9 Sumário
3.10 Exercı́cios
3.10.1 Exercı́cio 1
Classes e Objetos
24
CAPÍTULO 4. CLASSES E OBJETOS
public Carro(){}
Tipo[] varArray;
ou
Tipo varArray[];
ou
Tipo varArray[20];
sendo que nos dois primeiros casos, não é reservado espaço em memória para
os dados do array, enquanto no terceiro caso é reservado espaço para 20 itens
de tipo T ipo.
Assim como na secção 3.2.2 foram declarados arrays de tipos primiti-
vos, podemos declarar arrays de tipos de referência, nomeadamente Classes.
Observemos, assim, o seguinte exemplo:
Cliente[] clientes;
clientes = new Cliente[10];
System.out.println(clientes[0].getNome());
System.out.println(clientes[1].getNome());
Neste exemplo é declarado o array clientes de objetos de tipo Cliente.
Depois é reservado espaço em memória, para o array, para 10 clientes (i.e. 10
objetos de tipo Cliente). De seguida, é criado um cliente de nome ”Maria”,
o qual é atribuı́do à primeira posição do array clientes, e outro objeto de
tipo Cliente, com nome ”João”, o qual é atribuı́do à segunda posição do
array clientes. Por fim é impresso no ecrã o nome de cada um dos dois
primeiros clientes do array clientes.
4.8 Exercı́cios
4.8.1 Exercı́cio 1
Implemente a classe Retângulo, a qual tem dois atributos públicos de tipo
float, largura e altura. No método main() instancie um Retângulo, e altere
4.8.2 Exercı́cio 2
Altere a classe Retângulo anterior, de forma a que os seus atributos, largura
e altura, sejam privados. Crie também os getters e setters de largura e altura.
No método main() instancie um Retângulo, e altere a sua largura e altura.
4.8.3 Exercı́cio 3
Codifique a classe ContaBancária com os seguintes atributos e métodos:
(a) Uma variável de instância de acesso privado, titular, com tipo String.
(b) Uma variável de instância de acesso privado, saldo, com tipo double,
e com valor 0.0 por defeito.
4.8.4 Exercı́cio 4
Codifique a classe Banco com os seguintes atributos e métodos:
(a) Um array, contas, de objetos do tipo ContaBancária (ver exercı́cio
anterior).
Escreva a função main() para testar a classe Banco. Crie uma conta, efetue
depósitos e levantamentos e imprima no ecrã a informação da conta sempre
que atualiza o saldo.
4.8.5 Exercı́cio 5
Escreva em Java a classe Ventoinha que representa uma ventoı́nha do mundo
real. Esta classe tem os seguintes atributos e métodos:
(a) Uma variável de instância de acesso privado, ligado, com tipo boolean,
que indica se a ventoı́nha está ligada (true) ou não (f alse). O valor
por defeito é f alse.
(h) Um método toString() que devolve uma String com o estado atual da
ventoı́nha.
Escreva a função main() para testar a classe Ventoinha. Crie uma Ventoinha,
ligue-a, altere a velocidade, desligue-a e imprima no ecrã a informação do
estado da ventoı́nha, sempre que o mesmo é alterado.
4.8.6 Exercı́cio 6
Implemente a classe Singleton, a qual apenas deve permitir a existência de
uma única instância de si própria.