POO1 Ebook
POO1 Ebook
ORIENTADA A OBJETOS I
PROGRAMAÇÃO
ORIENTADA A OBJETOS I
Copyright © UVA 2019
Nenhuma parte desta publicação pode ser reproduzida por qualquer
meio sem a prévia autorização desta instituição.
R343
Rego, Angela
727 KB.
ISBN 978-85-5459-044-4
CDD – 469.800981
Apresentação 6
Autor 7
UNIDADE 1
• Características
• Ambientes de desenvolvimento
UNIDADE 2
UNIDADE 3
UNIDADE 4
6
AUTOR
7
UNIDADE 1
OBJETIVO
9
Histórico da linguagem Java
Desenvolvida na década de 1990 por James Gosling, da Sun Microsystems, foi inicial-
mente um pequeno trabalho anônimo, que, após a divulgação de suas ideias, foi apoiado
pela empresa Sun Microsystems, muito conhecida e forte no mercado de desenvolvi-
mento de estações de trabalho e de computação de alto desempenho. A Sun, então,
criou um grupo de trabalho para o projeto, que foi batizado de “The Green Project”, em
1991. Esse grupo foi separado das operações cotidianas da Sun, e uma equipe com 13
desenvolvedores trabalhou em um conjunto de escritórios próprios em Menlo Park, du-
rante 18 meses e sem comunicação com a matriz, para a criação de uma linguagem de
programação que fosse independente de plataforma, com a ideia de criar uma aplicação
em uma plataforma (write once) que pudesse ser executada em outras plataformas dife-
rentes, sem a necessidade de qualquer tipo de alteração (run anywhere).
Ainda naquela época, eles já previam a convergência entre dispositivos controlados di-
gitalmente e computadores. Podemos analisar um exemplo com os dispositivos eletro-
domésticos inteligentes ou ainda os smartphones, que se tornaram verdadeiros compu-
tadores pessoais, com sistema operacional próprio, diversos componentes e inúmeros
aplicativos.
10
A tecnologia Java é encontrada em equipamentos de redes, dispositivos voltados à inter-
net, sistemas de controle, supercomputadores, notebooks, desktops, smartphones, tablets,
dispositivos de jogos, máquinas de cartões de crédito, controles de robôs, entre outros.
MIDIATECA
A plataforma Java
A tecnologia Java conta com três tipos de plataformas, cada uma voltada a um tipo de
aplicação, sendo elas:
• Java SE (Java Standart Edition): são aplicações mais simples, para uso em compu-
tadores pessoais e de empresas.
• Java EE (Java Enterprise Edition): são aplicações mais complexas, que se baseiam
na arquitetura cliente × servidor, que dependem da comunicação de dados e execu-
tam em servidores, normalmente disponíveis em redes locais ou na internet, para
atender a demandas de aplicações do cliente.
11
• JME (Java Micro Edition): permite o desenvolvimento de aplicações voltadas ao en-
tretenimento e ao uso doméstico, tais como aplicativos para celulares, equipamen-
tos de blu-ray, set-top boxes, módulos de equipamento, impressoras, entre outros
equipamentos com aplicações voltadas a dispositivos móveis e integrados.
MIDIATECA
Esse ambiente instala o compilador e o interpretador Java, permitindo que você possa
criar aplicações nessa linguagem. Ele possui uma quantidade maior de arquivos e só
deve ser instalado pelos desenvolvedores, uma vez que pode atrapalhar o usuário final.
É possível criar aplicações apenas com o JDK, mas seu uso é mais complexo e depende
de conhecimentos avançados do sistema operacional para que o desenvolvedor possa
realizar essa tarefa. Dessa forma, é comum o uso de ferramentas apropriadas, tais como
o NetBeans e o Eclipse, que são específicas para o desenvolvimento de sistemas e muito
apropriadas ao desenvolvimento Java. Esse assunto voltará a ser discutido em breve
ainda neste conteúdo, mas é bom saber que essas ferramentas facilitarão o desenvolvi-
mento e os testes de seus aplicativos.
12
A seguir, podemos compreender o processo de desenvolvimento, no qual é necessário,
primeiramente, que o código do programa Java seja escrito em um editor de textos. Os
ambientes de desenvolvimento NetBeans e Eclipse já possuem um editor preparado para
facilitar a tarefa de edição do código. Após a edição, devemos então compilar o programa
Java para obtermos o arquivo com a extensão “class”, que é o segredo da portabilidade
Java. O arquivo com essa extensão é, então, executado a partir de um interpretador Java.
O processo de compilação do Java é diferente dos das demais linguagens, pois, en-
quanto nelas a compilação gera um código de máquina para um determinado ambiente
(hardware + software), esse processo em Java gera um código intermediário chamado
“bytecode”, um código especial de máquina, que não leva em consideração um ambiente
específico, mas sim um ambiente genérico que independe do ambiente de desenvolvi-
mento. O bytecode, então, é uma linguagem de máquina genérica que o processo de
compilação da linguagem Java usa para padronizar as aplicações Java independente-
mente do ambiente em que ocorreu o processo de compilação. Os bytecodes indepen-
dem do hardware e do software (sistema operacional) do computador no qual ocorreu a
compilação, permitindo que a interpretação ocorra em qualquer ambiente, mesmo que
seja diferente daquele em que ocorreu a compilação. O interpretador Java também é
conhecido como JVM (Java Virtual Machine), que nada mais é do que um software ca-
paz de interpretar os bytecodes em um ambiente específico. Basta que seja criado um
interpretador Java (JVM) para cada ambiente em que o Java poderá ser executado, que
esse interpretador poderá, então, executar qualquer aplicação Java desenvolvida para
ele. Dessa forma, temos uma JVM específica para cada ambiente ou dispositivo espe-
cífico, mas não podemos esquecer que, uma vez compilado um programa ou aplicação,
essa técnica permite que o programa seja executado em qualquer ambiente. Existem
diferentes versões da máquina virtual Java, uma para cada computador ou dispositivo
que irá executar as aplicações Java.
13
• O ambiente do JRE permite apenas a execução de aplicações Java.
MIDIATECA
O JRE instala apenas a máquina virtual Java (JVM), que é o interpretador Java apropriado
a cada máquina ou dispositivo, existindo então várias versões da JVM. Um computador
ou dispositivo com o JRE instalado poderá apenas executar aplicações Java, mas será
capaz de interpretar os bytecodes gerados em outros computadores com total compati-
bilidade, permitindo então a portabilidade da linguagem Java.
Prog.class Interpretador
Existe, ainda, um plug-in Java para navegadores de internet que permite a execução de
aplicações Java incorporadas às páginas HTML, os chamados “applets Java”.
Como vimos, a linguagem Java é híbrida: enquanto as demais são compiladas ou inter-
pretadas, a linguagem Java é compilada e interpretada, sendo necessariamente obriga-
tória a compilação para o bytecode, e a execução é sempre interpretada pela máquina
virtual Java (JVM), que deve ser instalada no ambiente de execução do cliente. Essa ca-
racterística torna a linguagem Java muito diferente das demais linguagens, contribuindo
para a portabilidade das aplicações Java. Atualmente, o interpretador Java realiza uma
compilação ( just in time) com o intuito de aumentar o desempenho das aplicações. Isso
fez com que as execuções das aplicações se tornassem mais rápidas do que as lingua-
gens de script e mais próximas, mas ainda abaixo do desempenho das linguagens com-
piladas diretamente para um determinado ambiente.
14
MIDIATECA
Curiosidade
15
• Execução simultânea, com o uso de múltiplas threads.
• Gerenciamento de memória, com sua limpeza (garbage collection).
• A JVM (máquina virtual Java) possui proteção contra a execução de aplicações
malcomportadas que possam vir a paralisar o sistema.
• Suporte à programação distribuída e à multitarefa.
• Gerenciamento de memória virtual por meio da JVM.
• Alto desempenho, sendo mais rápida do que linguagens de script, mas é mais lenta
do que linguagens de programação compiladas para um ambiente.
• Suas aplicações podem utilizar recursos da rede de forma tão simples quanto
acessar arquivos locais.
• Atualmente, diminuiu os problemas de desempenho com a inclusão da compilação
just in time em vez de uma simples interpretação executada pela máquina virtual.
16
Características
Comentários
Identificadores
Identificadores são usados para dar nomes aos elementos dos nossos programas, tais
como: classes, objetos, interfaces, variáveis, constantes, métodos, atributos etc.
17
• Após o primeiro caractere, passam a ser permitidas novas letras (maiúsculas ou
minúsculas), os símbolos $ e _, além dos dígitos de 0 a 9 (um identificador não pode
iniciar por um dígito).
• Não há limite para o número de letras, símbolos e dígitos em um identificador.
• Você deve evitar o uso de caracteres acentuados e de outros símbolos ao nomear
um identificador (ç, á, é, í, ó, ú, â, ê, ô, à, ã, õ, %, #, @ etc.).
• Identificadores na linguagem Java são case-sensitive, ou seja, fazem distinção
entre letras maiúsculas e minúsculas: pessoa, PESSOA e Pessoa são identificado-
res diferentes.
• Exemplos de identificadores permitidos:
– Identificador
– UserName
– Username
– _sys_var1
– $change
18
Declaração de variáveis auxiliares
A linguagem Java possui grande semelhança com a sintaxe utilizada nas linguagens C/
C++, e todas as variáveis em Java devem ser tipadas (o tipo de dado deverá ser explicita-
mente informado).
Importante
A linguagem Java possui nove tipos de dados básicos, sendo oito deles primitivos e um
tipo especial. Esses dados formam a base para o armazenamento em memória de todos
os tipos suportados pela linguagem.
A boa prática em programação Java determina que variáveis e atributos devem ser
identificados pelo uso de letras minúsculas.
19
– Caractere (char): responsável por armazenar um único caractere ou caracte-
re especial (indicado por iniciar com uma barra invertida).
Exemplos:
‘\r’ Enter.
‘\t’ Tabulação.
– Inteiros (byte, short, int e long): responsáveis por armazenar valores inteiros,
cada tipo possui uma limitação de valores, entre os limites inferior e superior,
a fim de permitir economia de espaço de memória no armazenamento de pe-
quenos valores.
20
Exemplos:
Exemplos:
A linguagem Java realiza uma conversão de qualquer tipo numérico para double
sempre que um tipo diferente de double é atribuído a uma variável double. Essa
característica é chamada de “coerção” e é empregada na linguagem Java.
21
• Tipo especial – Responsável por armazenar o valor em uma classe, com a possi-
bilidade de uso dos métodos disponibilizados por ela.
– String: o tipo String não é um tipo primitivo, mas especial. O valor é armazena-
do em uma classe, por isso esse tipo é iniciado com letra maiúscula, ao contrá-
rio dos tipos primitivos, que sempre se iniciam por letras minúsculas. Esse tipo
é usado para armazenar uma sequência de caracteres e possui várias ações
(métodos) que podem ser usadas sobre os valores armazenados. Variáveis e
atributos do tipo String também devem ter identificadores iniciados por letras
minúsculas.
Valores constantes
Valores constantes em Java são obtidos com o emprego do modificador final. Qualquer
tipo associado a ele fará com que, ao ser inicializado, o valor não possa mais ser alterado.
A boa prática em programação Java define que constantes devem ser identificadas por
meio do uso de letras maiúsculas.
Exemplos:
Operadores
• Operadores aritméticos:
Operador Descrição
= Atribuição
+ Soma
- Subtração
* Multiplicação
/ Divisão
22
Exemplos:
Importante
Todo cálculo entre inteiros resulta em um inteiro, mesmo a divisão. Para uma divisão
entre inteiros que se queira a parte fracionária, é necessário converter o tipo, e isso
pode ser feito por meio de cast.
Exemplos:
int x=7, y = 3, z;
z = x / y; // z valerá 2: 7 / 3 => 2 e resto 1.
int x=7, y = 3;
float z;
z = (float) x / y;
23
• Operadores de incremento e decremento:
– Pré-incremento:
x = 10;
x = x + 1; O valor da variável x é 11
ou
x = 10;
++x; O valor da variável x é 11.
– Pós-incremento:
x = 10;
x = x + 1; O valor da variável x é 11
ou
x = 10;
x++; O valor da variável x é 11.
Exemplo 1:
int y, x = 10;
y = ++x ; => neste momento, a variável x foi primeiramente incremen-
tada e vale 11, já a variável y receberá o valor de x e também valerá 11.
Exemplo 2:
int y, x =10;
y = x++; => neste momento, a variável x será pós-incrementada,
e, sendo assim, a variável y receberá primeiramente o valor de
x e valerá 10; posteriormente, a variável x será incrementada e
passará a valer 11.
24
Pré-decremento e o pós-decremento:
--x; e x--; => Valem as mesmas regras apresentadas para o incremento, mas dimi-
nuem uma unidade respectivamente.
• Operadores relacionais:
Operador Descrição
== Igualdade/comparação
!= Negação
Exemplos:
if(a > b)
if(a+b >= c)
Operador Descrição
! NÃO lógico
&& E lógico
|| OU lógico
Exemplos:
25
Precedência na avaliação: !, &&, ||
• Operadores de bits:
Operador Descrição
& E entre bits
| OU entre bits
Precedência: &, ^, |
Exemplos:
128 64 32 16 8 4 2 1
a= 0 0 1 0 1 1 0 1 = 45
b= 0 1 0 0 0 1 1 0 = 70
c= 0 0 0 0 0 1 0 0 =4
128 64 32 16 8 4 2 1
a= 0 0 1 0 1 1 0 1 = 45
b= 0 1 0 0 0 1 1 0 = 70
c= 0 1 1 0 1 0 1 1 = 107
26
byte a = 45, b = 70, c=0;
c = a | b; // o valor de c será 111
128 64 32 16 8 4 2 1
a= 0 0 1 0 1 1 0 1 = 45
b= 0 1 0 0 0 1 1 0 = 70
c= 0 1 1 0 1 1 1 1 = 111
As operações com bits são muito importantes não apenas para a definição de máscaras
e submáscaras de rede, mas principalmente para as operações relacionadas à criptogra-
fia para a segurança de dados. Nesse contexto, a operação de OU exclusivo é fundamen-
tal para a realização das operações de criptografia.
Pode ser usado em expressões aritméticas para tomar uma decisão no momento
do cálculo, para definir um valor de retorno, entre outras aplicações.
Exemplo:
27
• Interfaces – Nomes de interfaces seguem o mesmo formato de classes.
Exemplo: cadastrar( ) { }
Exemplos:
class AlunoGraduacao { }
interface AtletaProfissional { }
double alturaPredio;
setNome () { }
28
• Controles de estruturas – Convencionou-se o uso obrigatório de { } (chaves).
– Estruturas condicionais:
- Se (if):
if (condição) {
instruções;
}// A cláusula else é opcional.
if (condição) {
instruções;
}
else {
instruções;
}
29
- Se / Senão Se / Senão (if ... else if ... else):
A cláusula if ocorre apenas uma vez.
A cláusula else if pode ocorrer nenhuma ou várias vezes.
A cláusula else pode ocorrer apenas uma vez.
if (condição1) {
instruções;
}
else if (condição2) {
instruções;
}
else if (condição3) {
instruções;
}
else {
instruções;
}
switch (variável) {
case 1 : instruções;
break;
case 2 : instruções;
break;
case 3 : instruções;
break;
default: instruções para condições não previstas anteriormente;
}
30
switch (variável) // Pode-se simular o uso do OU em um switch:
{
case 2 : numeroDias = 28;
break;
case 4 :
case 6 :
case 9 :
case 11: numeroDias = 30;
break;
case 1 : switch(letra){
case 3 : case ‘a’:
case 5 : case ‘A’: opcao = 1;
case 7 : break;
case 8 : ...
case 10 :
case 12 : numeroDias = 31;
break;
default: System.out.println(“Mês não identificado”);
}
• Estruturas de repetição:
– Para (for):
Estrutura de repetição controlada por uma ou mais variáveis contadoras e ca-
racterizadas pela existência de três parâmetros (opcionais):
1. Valor inicial.
2. Condição para parada das iterações.
3. Quantidade de incrementos/decrementos a cada iteração.
Exemplos:
31
{
instruções;
}
// Repetição controlada por duas variáveis:
for (x=1, y=2; x*y<valor; x++, y+=2)
{
instruções;
}
// Repetição sem fim
for ( ; ; ) {
instruções; // você pode usar uma condicional if () e a instrução
// break, que encerrará a repetição
}
32
MIDIATECA
33
Ambientes de desenvolvimento
JDK
Clique sobre o botão “Download” do Oracle JDK versão Java SE 12.0.1 e escolha:
Windows 158.49 MB jdk-12.0.1_windows-x64_bin.exe
Não se esqueça de aceitar o contrato de licença após analisá-lo e de se cadas-
trar na Oracle caso seja necessário.
Depois, basta instalá-lo seguindo as orientações do instalador. Após a instala-
ção, não se esqueça de reiniciar a máquina para que as configurações sejam
atualizadas. Essa versão irá atender tanto ao Eclipse como ao NetBeans.
MIDIATECA
34
NetBeans
Faça a escolha pela versão mais recente e pelo pacote “bin” (neste momento,
é a versão 11.0), que contém os executáveis da ferramenta; o pacote “source”
contém todos os códigos do projeto do NetBeans, que foi feito em Java.
Essa versão não precisa ser instalada — basta descompactar o arquivo, e você
encontrará o executável na pasta “bin” do NetBeans.
Se quiser, você poderá clicar sobre o executável com o botão direito do mouse
e enviar para a área de trabalho para criar um atalho no desktop.
MIDIATECA
MIDIATECA
35
Eclipse
MIDIATECA
Usaremos o seguinte programa para testar as duas ferramentas, e você decidirá qual
prefere utilizar no desenvolvimento de seus projetos:
import java.util.Scanner;
36
}
else {
if((nota2 <= nota1) && (nota2 <= nota3)) {
menorNota = nota2;
}
else {
menorNota = nota3;
}
}
media = (((nota1 + nota2 + nota3) - menorNota)) /2.0;
System.out.println(“A média das 2 maiores notas é:” + media);
sc.close();
}
}
37
Para criar um novo projeto, clique em “File” e, em seguida, “New Project”.
Para a disciplina, sempre use “Java with Ant” e “Java Application”. Clique em “Next”
para continuar.
38
Defina o nome do projeto como “Media”. Clique em “Finish” para terminar e criar o
projeto.
39
Faça a codificação do programa na página de edição.
Para executar esse código, selecione o arquivo da classe na área de projetos e clique
com o botão direito do mouse escolhendo “Run File” para executar o código.
40
O código será executado na área de Output abaixo do código. Todas as áreas po-
dem ser redimensionadas, assim como foi feito no exemplo ao aumentar a área de
Output para analisar a execução.
Na tela principal do Eclipse, acesse o “Menu File”, em seguida, a opção “New”, e es-
colha “Java Project”.
41
Defina o nome do projeto “Media” e clique em “Finish” para criar o projeto.
42
Crie uma classe Java para realizar a codificação da aplicação. Selecione o projeto e
clique com o botão direito do mouse, selecionando “New” e “Class”.
43
Área de codificação da classe pronta para a edição do código.
44
Execute o código, selecione a classe e clique com o botão direito do mouse sobre
ela, escolhendo “Run As” e “Java Application”.
45
NA PRÁTICA
O programa deverá solicitar ao usuário seu peso e sua altura e retornar o valor
do IMC e em qual situação ele se encontra, de acordo com a tabela a seguir.
IMC Resultado
Menos do que 18,5 Abaixo do peso
46
Resumo da Unidade 1
CONCEITO
47
Referências
DEITEL, P. Java: como programar. 10. ed. São Paulo: Pearson Education do Brasil, 2017.
Biblioteca Virtual.
SCHILDT, H. Java para iniciantes: crie, compile e execute programas Java rapidamente.
6. ed. Porto Alegre: Bookman, 2015. Minha Biblioteca.
48
UNIDADE 2
Os conceitos básicos da
programação orientada a
objetos utilizando o Java
INTRODUÇÃO
OBJETIVO
50
Classes, objetos, atributos e métodos; mé-
todos de acesso
Classes
Toda classe representa um tipo, ou seja, assim como temos os tipos básicos (byte, short,
int, long, float, double, char e boolean) e o tipo especial (String), toda classe representa
uma estrutura de dados que pode armazenar um conjunto de características.
Na programação orientada a objetos, temos dois tipos de membros em uma classe, que
são responsáveis por determinar as características e ações dos objetos nas aplicações.
É na aplicação que os objetos são criados e realizam suas ações.
oAtributos – Os atributos de uma classe são responsáveis por descrever o objeto quanto
a suas características. Cada objeto deve ser analisado, e apenas as características
importantes ao sistema devem ser levadas em consideração. As características de um
automóvel para um sistema de estacionamento podem se resumir em modelo, cor e placa,
sendo suficientes para representar o automóvel nesse contexto. Já para um sistema mais
abrangente, como o Detran, por exemplo, a codificação do chassi, o fabricante, o número
do Renavam e potência são igualmente importantes. Dessa forma, é necessário analisar
o contexto do projeto de sistema (minimundo) e determinar quais são as características
importantes de cada objeto ao contexto do sistema. Em um sistema acadêmico, por
exemplo, são importantes o nome, matrícula, CR, curso, entre outras características, mas
o time para o qual o aluno torce ou a sua religião não tem importância. Atributos devem,
então, definir um tipo de dado e um identificador para cada característica relevante do
objeto para o sistema.
51
Atributos não devem ser identificados de formas diferentes: uma vez que ocorra uma
definição de projeto sobre o seu identificador, não devemos alterá-lo. A boa prática em
desenvolvimento Java facilitará o desenvolvimento em equipes se todos usarem sempre
o identificador-padrão do projeto. Qualquer mudança atrasará o projeto, e provavelmente
parte dele precisará ser alterada. Se um atributo foi definido como NúmeroPessoas:
inteiro, ele deve ser declarado como o atributo:
int numeroPessoas;
Exemplo
52
auto2.placa = “SAL1A02”;
auto3.placa = “SAO1A03”;
auto4.placa = “VIT1A04”;
auto5.placa = “BEL1A05”;
System.out.println(“Placa do auto1: “ + auto1.placa);
System.out.println(“Placa do auto2: “ + auto2.placa);
System.out.println(“Placa do auto3: “ + auto3.placa);
System.out.println(“Placa do auto4: “ + auto4.placa);
System.out.println(“Placa do auto5: “ + auto5.placa);
}
}
Notas:
1. A classe Automovel foi definida uma única vez, e a aplicação criou cinco
diferentes objetos Automovel.
2. Para cada objeto Automovel criado, foi reservada uma região de memória
para armazenar as suas características (atributos).
3. As características dos diferentes objetos não se misturam, uma vez que a
atribuição de cada característica exige a identificação do objeto; dessa forma,
as atribuições das placas não se misturaram.
4. Exibir todas as características de cada Automovel exigiria uma grande
quantidade de programação na aplicação, com códigos quase repetidos,
alterando apenas o identificador de cada objeto.
o Métodos – Os métodos de uma classe são responsáveis pelas ações que o objeto
pode realizar. Enquanto os atributos se resumem apenas na declaração das suas
características, os métodos possuem um conjunto de instruções que serão executadas
para realizar ações ou funções referentes ao objeto. No caso acima, como temos oito
atributos (características), a impressão de cada atributo de cada objeto poderia demandar
um conjunto de 40 instruções (cinco objetos x oito atributos). Podemos, então, criar dois
métodos: um método capaz de realizar a exibição dos dados do objeto e outro para
realizar a entrada de dados dos atributos do objeto. Esses métodos serão responsáveis
pela entrada de dados para atribuição das características e por exibir todos os atributos
do objeto. Ambos os métodos serão desenvolvidos apenas uma vez e poderão ser
executados por todos os objetos criados em qualquer aplicação. As ações ocorrerão
sempre sobre o objeto que estiver identificado na chamada da ação.
53
Exemplo
import java.util.Scanner;
public class Automovel {
// Atributos
String modelo, cor, placa;
int hora, minuto, dia, mes, ano;
// Métodos
public void entradaDados ( ){
Scanner sc = new Scanner(System.in);
System.out.println(“Digite o Modelo :”);
modelo = sc.nextLine();
System.out.println(“Digite a Cor :”);
cor = sc.nextLine();
System.out.println(“Digite a Placa :”);
placa = sc.nextLine();
System.out.println(“Digite a Hora :”);
hora = Integer.parseInt(sc.nextLine());
System.out.println(“Digite o Minuto :”);
minuto = Integer.parseInt(sc.nextLine());
System.out.println(“Digite o Dia :”);
dia = Integer.parseInt(sc.nextLine());
System.out.println(“Digite o Mês :”);
mes = Integer.parseInt(sc.nextLine());
System.out.println(“Digite o Ano :”);
ano = Integer.parseInt(sc.nextLine());
}
public void imprimir ( ){
System.out.println(“Modelo : “ + modelo);
System.out.println(“Cor : “ + cor);
System.out.println(“Placa : “ + placa);
System.out.println(“Hora : “ + hora);
System.out.println(“Minuto : “ + minuto);
System.out.println(“Dia : “ + dia);
System.out.println(“Mês : “ + mes);
System.out.println(“Ano : “ + ano);
}
}
54
Em uma aplicação, podemos, então, criar diferentes objetos Automovel,
baseados em apenas uma classe:
Notas:
1. A classe Automovel foi alterada (sofreu uma evolução), e foram criados dois
métodos.
2. Os métodos entradaDados e imprimir passaram a realizar as ações de
atribuições e de exibição dos dados armazenados, respectivamente.
3. Para cada objeto Automovel criado, os métodos são executados, mas a
entrada de dados e a exibição ocorrem separadamente para cada objeto, uma
vez que devemos sempre identificar o objeto que realizará a ação.
4. Os métodos foram reaproveitados por todos os objetos da aplicação, mas
eles também estão disponíveis para qualquer outro objeto em qualquer outra
aplicação que crie objetos da classe Automovel criada.
55
5. O objeto Scanner sc foi definido dentro do método de entrada de dados,
porque ele não representa uma característica do objeto Automovel; esse objeto
é apenas auxiliar para a realização da ação do método.
Um outro ponto importante é a evolução das classes: uma vez que elas são bibliotecas
disponíveis para as aplicações, essas classes podem ser utilizadas em várias aplicações
diferentes. É normal que determinadas aplicações tenham algumas exigências a mais
do que outras; dessa forma, as classes na programação orientada a objetos podem
sofrer evoluções, mas isso não quer dizer que elas passarão a atender a apenas uma
aplicação. Elas devem evoluir mantendo a compatibilidade com as aplicações anteriores.
Essa forma de evolução permite que cada classe criada possa ser utilizada em diversas
aplicações distintas, daí a ideia de biblioteca de classes.
Objetos
56
Exemplo
Exemplo:
// Aplicação 1:
public class AppAutomovel {
public static void main(String[] args) {
// TODO Auto-generated method stub
// criação dos 5 objetos
Automovel auto1 = new Automovel();
Automovel auto2 = new Automovel();
Automovel auto3 = new Automovel();
Automovel auto4 = new Automovel();
Automovel auto5 = new Automovel();
}
}
// Aplicação 2:
public class AppAuto {
public static void main(String[] args) {
// TODO Auto-generated method stub
// criação dos 5 objetos
Automovel a1 = new Automovel();
Automovel a2 = new Automovel();
Automovel a3 = new Automovel();
}
}
Notas:
57
Resumindo:
MIDIATECA
Métodos de acesso
São métodos especiais que são utilizados para evitar acesso direto aos seus atributos.
Uma atribuição direta a um atributo não permite que possamos analisar se o valor a ser
atribuído está de acordo com o realizado.
58
Exemplo
Exemplos:
auto1.hora = -3;
auto1.placa = “AAA”;
auto1.modelo = “”;
Notas:
Nesses casos, as atribuições ocorreram sem que nenhum tipo de teste pudesse ser
realizado a fim de evitar essas atribuições incorretas. Outro ponto importante que será
visto mais adiante é o conceito de encapsulamento, em que os atributos deverão estar
protegidos para que não possam ser acessados indiscriminadamente pelas aplicações.
Esse conceito é responsável por proteger os atributos de um objeto, dando mais segurança
para que eles não sejam alterados diretamente pela aplicação.
o Métodos setters
59
Devem realizar
Possuem sempre
Devem ser públicos a atribuição do
um parâmetro do
(public), para que São sempre do tipo conteúdo do
mesmo tipo do
possam ser usados void, porque nunca parâmetro da
atributo que
em qualquer retornam nada. propriedade
realizará a
aplicação. correspondente
atribuição.
do objeto.
Exemplo
Exemplos:
60
Notas:
Você ainda pode incluir testes para analisar se os valores estão de acordo com o esperado:
Exemplo
61
else {
System.out.println(“valor inválido, não foi atribuído”);
}
}
Notas:
o Métodos getters
Nunca são do
Devem ser Devem apenas
tipo void, porque
públicos (public) Não possuem realizar o
sempre retornam
para que possam parâmetros, retorno do valor
um valor, devendo
ser usados porque não armazenado na
ser do mesmo
em qualquer recebem valores. propriedade do
tipo do atributo
aplicação. objeto.
que irá retornar.
62
Exemplo
Exemplos:
Notas:
63
o Atualização da classe (evolução)
A classe Automovel foi atualizada, mas a aplicação usada anteriormente não precisará
ser alterada, uma vez que a classe permanece compatível com as aplicações anteriores.
Exemplo
import java.util.Scanner;
public class Automovel {
// Atributos
String modelo, cor, placa;
int hora, minuto, dia, mes, ano;
// Métodos de acesso
public String getModelo() {
return modelo;
}
public void setModelo(String m) {
if(!m.isEmpty() ) {
modelo = m;
}
else {
System.out.println(“valor inválido, não foi atribuído”);
}
}
public String getCor() {
return cor;
}
public void setCor(String c) {
cor = c;
}
public String getPlaca() {
return placa;
}
64
public void setPlaca(String p) {
if(p.length()==7) {
placa = p;
}
else {
System.out.println(“valor inválido, não foi atribuído”);
}
}
public int getHora() {
return hora;
}
public void setHora(int h) {
if (h >= 0 && h <=24){
hora = h;
}
else {
System.out.println(“valor inválido, não foi atribuído”);
}
}
public int getMinuto() {
return minuto;
}
public void setMinuto(int m) {
minuto = m;
}
public int getDia() {
return dia;
}
public void setDia(int d) {
dia = d;
}
public int getMes() {
return mes;
}
public void setMes(int m) {
mes = m;
}
public int getAno() {
return ano;
}
65
public void setAno(int a) {
ano = a;
}
// demais métodos
public void entradaDados ( ){
Scanner sc = new Scanner(System.in);
System.out.println(“Digite o Modelo :”);
setModelo(sc.nextLine());
System.out.println(“Digite a Cor :”);
setCor(sc.nextLine());
System.out.println(“Digite a Placa :”);
setPlaca(sc.nextLine());
System.out.println(“Digite a Hora :”);
setHora(Integer.parseInt(sc.nextLine()));
System.out.println(“Digite o Minuto :”);
setMinuto(Integer.parseInt(sc.nextLine()));
System.out.println(“Digite o Dia :”);
setDia(Integer.parseInt(sc.nextLine()));
System.out.println(“Digite o Mês :”);
setMes(Integer.parseInt(sc.nextLine()));
System.out.println(“Digite o Ano :”);
setAno(Integer.parseInt(sc.nextLine()));
}
public void imprimir ( ){
System.out.println(“Modelo : “ + getModelo());
System.out.println(“Cor : “ + getCor());
System.out.println(“Placa : “ + getPlaca());
System.out.println(“Hora : “ + getHora());
System.out.println(“Minuto : “ + getMinuto());
System.out.println(“Dia : “ + getDia());
System.out.println(“Mês : “ + getMes());
System.out.println(“Ano : “ + getAno());
}
}
Notas:
66
2. Não existe ordem para os métodos e atributos de uma classe; apenas por
convenção, devemos definir os atributos no início, para facilitar a identificação.
3. Apenas por uma questão de organização, os métodos de acesso foram
colocados no início, mas alguns desenvolvedores ainda os separam em um
grupo para os setters e outro para os getters.
4. Os métodos entradaDados e imprimir foram alterados e passaram a utilizar
os métodos de acesso, e não mais o acesso direto aos atributos da classe.
Você ainda poderá melhorar os métodos setters que estão sem os testes de verificação
de dados para entender melhor como realizar
essa tarefa.
67
Polimorfismo de sobrecarga de operadores
e de métodos
Polimorfismo
68
Exemplo
“Resultado: “ + (5.0 + (3 + 6) + ++ x)
Ações:
Resultado: 27.0
69
Importante
A assinatura do método leva em conta apenas os tipos de dados e sua ordem, não levan-
do em consideração os identificadores dos parâmetros.
O método definido como int meuMetodo( int a, double b, String c ) possui como assi-
natura: int meuMetodo( int, double, String ).
Repare que apenas os tipos e a ordem dos tipos na área de parâmetros são levados em
consideração.
Dessa forma, os métodos a seguir não atendem ao critério de sobrecarga, porque pos-
suem a mesma assinatura:
70
Importante
O método setNome não recebe parâmetros e serve para limpar (eliminar) o valor armaze-
nado no atributo modelo:
As assinaturas dos dois métodos são diferentes e, por isso, podem existir na mesma
classe.
71
A linguagem Java resolve esse problema durante a execução da aplicação. O método
correto será executado em função de uma avaliação que será realizada na sintaxe da
chamada do método. Vamos analisar o seguinte exemplo:
auto1.setModelo();
Nota:
Dessa forma, não importa quantos métodos com o mesmo nome existam em uma
mesma classe. Quando isso ocorre, a chamada ao método que está sendo realizada
irá avaliar e transferir a execução para o método sobrecarregado que possuir a mesma
assinatura da chamada.
72
Exemplo
Métodos de mesmo nome em uma mesma classe (sobrecarga) podem receber diferen-
tes mensagens (assinaturas) e responder à chamada de diferentes formas.
Exemplo
Os exemplos a seguir podem pertencer à mesma classe, uma vez que, apesar
de todos terem a mesma quantidade de parâmetros, as suas assinaturas são
diferentes:
73
O uso do polimorfismo de sobrecarga de métodos está associado à evolução das clas-
ses. Imagine que você tem uma classe de acesso aos sistemas, com identificação do
usuário, e esse método possui a seguinte assinatura:
Vários sistemas já em funcionamento usam esse método para realizar o login dos usuá-
rios, mas um novo cliente precisa que, além do nome de login e da senha, seja verificado
um código gerado por um token. Você não precisa criar uma nova classe, basta evoluir
essa classe implementando uma nova forma de acesso:
Importante
A classe agora pode atender o seu novo cliente e ainda se mantém compatível
com as aplicações dos antigos clientes.
MIDIATECA
74
Métodos construtores e sobrecarga de mé-
todos construtores
Métodos construtores
75
Exemplo
Exemplo:
Uso:
Automovel a1 = new Automovel( “Uno”, “Verde”, “RIO1A00”, 10, 23, 23, 06, 2019 );
O uso desse método permite que possamos criar um objeto automóvel já com todos os
valores atribuídos; isso é importante quando estamos trabalhando com bases de dados.
Como o objeto a1 já recebeu os valores para serem atribuídos às suas propriedades, o
objeto não precisará da entrada de dados ou outra forma de atribuição.
Por outro lado, as aplicações anteriores não irão mais funcionar com a classe Automovel.
Isso ocorre porque a forma antiga de instanciação deixou de ser válida.
Porém, quando criamos algum método construtor, isso não acontece. Passa a ser uma
questão de segurança: como o método construtor controla a criação do objeto, só podem
ser criados objetos utilizando construtores existentes na classe.
76
Importante
Essa é uma medida de segurança, uma vez que não será permitido que sejam
criados objetos de qualquer forma, apenas obedecendo aos construtores
disponíveis.
public Automovel() {
}
77
A instanciação ou criação de um objeto segue a seguinte sintaxe:
Podemos, então, evoluir a classe Automovel incluindo alguns métodos construtores, mas
lembre-se de que não poderá haver métodos com o mesmo nome, construtores ou não,
e com a mesma assinatura.
// métodos construtores
public Automovel() { } // construtor vazio para a classe
public Automovel( String pl) { // só a placa
setPlaca(pl);
}
public Automovel( String pl, int ho, int mi) { // poucos atributos
setPlaca(pl);
setHora(ho);
setMinuto(mi);
}
public Automovel(String pl, int ho, int mi, int di, int me, int an) {// alguns atributos
setPlaca(pl);
setHora(ho);
setMinuto(mi);
setDia(di);
setMes(me);
setAno(an);
}
public Automovel(String mo, String co, String pl, int ho,
int mi, int di, int me, int an) { // todos os atributos
setModelo(mo);
setCor(co);
setPlaca(pl);
setHora(ho);
setMinuto(mi);
78
setDia(di);
setMes(me);
setAno(an);
}
Importante
MIDIATECA
79
NA PRÁTICA
80
Resumo da Unidade 2
CONCEITO
81
Referências
DEITEL, P. Java: como programar. 10. ed. São Paulo: Pearson Education do Brasil, 2017.
p. 312. Biblioteca Virtual.
SCHILDT, H. Java para iniciantes: crie, compile e execute programas Java rapidamente.
6. ed. Porto Alegre: Bookman, 2015. Minha Biblioteca.
82
UNIDADE 3
Os conceitos avançados da
programação orientada a
objetos utilizando o Java
INTRODUÇÃO
OBJETIVO
84
A herança de classes, o reaproveitamento
de membros das classes e o polimorfismo
de sobrescrita
Com a herança, também podemos substituir métodos da superclasse que não sejam
específicos da subclasse por um novo método mais pertinente ou substituir o método da
superclasse por um método que aproveite o método da superclasse, estendendo-o com
a inclusão de mais ações. Esse conceito é conhecido como polimorfismo de sobrescrita
e só ocorre em situação de herança de classes e com a substituição do método original
da superclasse por um método com a mesma assinatura na subclasse.
85
Generalização Especialização
Quando uma subclasse herda os membros de Quando uma subclasse herda os membros de
uma única superclasse por vez. mais de uma superclasse ao mesmo tempo.
Importante
Superclasse de B
Subclasse de A
B
A classe B herda da classe A.
86
Superclasse de B
A
Subclasse de A
B
Superclasse de C
Subclasse de B
C
A classe C herda da classe B, e a classe B herda da classe A.
Superclasse de B e C
Subclasse de A Subclasse de A
B C
As classes B e C herdam da classe A.
Superclasse de B e C
Subclasse de A
Subclasse de A
C
B Superclasse de D e E
Subclasse de C Subclasse de C
D E
A classe B herda da classe A, as classes D e E herdam da classe C, e a classe C herda da classe A.
87
Exemplos de herança múltipla:
Superclasse de C Superclasse de C
A B
Subclasse de A e B
C
A classe C herda ao mesmo tempo das classes A e B.
A B C
Subclasse de A e B Subclasse de B e C
D E
A classe D herda ao mesmo tempo das classes A e B, e a classe
E herda ao mesmo tempo das classes B e C.
Uma classe, para estender outra (se tornar uma subclasse), deve usar o modificador ex-
tends, que a tornará uma subclasse da classe estendida.
Exemplos:
1 -
public class A { // ... } // Classe A: Superclasse de B
public class B extends A { // ... } // Classe B: Subclasse de A
2 -
public class A { // ... } // Classe A: Superclasse de B
public class B extends A { // ... } // Classe B: Subclasse de A – Superclasse de C
public class C extends B { // ... } // Classe C: Subclasse de B
88
3 -
public class A { // ... } // Classe A: Superclasse
public class B extends A { // ... } // Classe B: Subclasse de A
public class C extends A { // ... } // Classe C: Subclasse de A
4 -
public class A { // ... } // Classe A: Superclasse de B e de C
public class B extends A { // ... } // Classe B: Subclasse de A
public class C extends A { // ... } // Classe C: Subclasse de A e Superclasse de D e E
public class D extends C { // ... } // Classe D: Subclasse de C
Existem ainda várias outras estruturas de herança que podem ser implementa-
das, mas sempre respeitando a herança simples em Java.
Como na linguagem Java não temos a implementação da herança múltipla, não serão
apresentados exemplos práticos de herança múltipla.
Polimorfismo de sobrescrita
89
Pode ocorrer quando a funcionalidade apresentada na superclasse não atende ao requi-
sito da especialista da subclasse:
Exemplo
O exemplo anterior é um bom exemplo, dado que apenas desejamos incluir a exibição do
sexo, uma vez que o nome já é exibido pelo método na superclasse.
90
Exemplo
Exemplo
Exemplo prático:
91
fundamentais no sistema e possuem algumas características semelhantes.
Vamos analisar as classes a seguir com alguns atributos determinados para o
sistema após um projeto de análise:
Classes Atributos
Matrícula : texto
Nome : texto
Celular : texto
Aluno
Idade : inteiro
CódigoCurso : inteiro
CR : real
Matrícula : texto
Nome : texto
Celular : texto
Professor Idade : inteiro
CódigoCarreira : inteiro
Salário : real
Titulação : texto
Matrícula : texto
Nome : texto
Celular : texto
Funcionario Idade : inteiro
CódigoCarreira : inteiro
Salário : real
Função : texto
Após a análise dos atributos, constatamos que os atributos a seguir são co-
muns às três classes:
• Matrícula : texto
• Nome : texto
• Celular : texto
• Idade : inteiro
92
Também podemos constatar que os atributos a seguir são comuns às classes
professor e funcionário:
• CódigoCarreira : inteiro
• Salário : real
• Matrícula : texto
• Nome : texto
Pessoa
• Celular : texto
• Idade : inteiro
• CódigoCarreira : inteiro
Colaborador
• Salário : real
93
Exemplo
Agora vamos criar o projeto herança no IDE escolhido (NetBeans ou Eclipse) com as
classes determinadas e uma classe de teste (aplicação). Para este exemplo prático,
vamos implementar pelo menos cinco métodos construtores, os métodos de aces-
so (setters e getters), além dos métodos de entrada de dados (entrada), de exibição
dos dados do objeto (imprimir) e do método de cadastro (cadastrar), que deve rece-
ber todos os dados do objeto e realizar as atribuições.
import java.util.Scanner;
94
if(!cel.isEmpty()) {
celular = cel;
}
}
public int getIdade() {
return idade;
}
public void setIdade(int ida) {
if(ida>=0) {
idade = ida;
}
}
public Pessoa() { }
public Pessoa(String nome, int idade) {
setNome(nome);
setIdade(idade);
}
public Pessoa(String matricula, String nome) {
setMatricula(matricula);
setNome(nome);
}
public Pessoa(String matricula, String nome, int idade) {
setMatricula(matricula);
setNome(nome);
setIdade(idade);
}
public Pessoa(String matricula, String nome, String celular) {
setMatricula(matricula);
setNome(nome);
setCelular(celular);
}
public Pessoa(String matricula, String nome, String celular, int idade) {
setMatricula(matricula);
setNome(nome);
setCelular(celular);
setIdade(idade);
}
public void cadastrar(String matricula, String nome, String celular,int idade){
setMatricula(matricula);
setNome(nome);
setCelular(celular);
setIdade(idade);
}
95
System.out.println(“Matrícula :” + getMatricula());
System.out.println(“Nome :” + getNome());
System.out.println(“Celular :” + getCelular());
System.out.println(“Idade :” + getIdade());
}
public void entrada() {
// Como o Scanner não é um atributo da classe,
// ele deve ser declarado dentro do método em que será utilizado,
// como um objeto auxiliar
Scanner ent = new Scanner(System.in);
System.out.println(“Matrícula :”);
setMatricula(ent.nextLine());
System.out.println(“Nome :”);
setNome(ent.nextLine());
System.out.println(“Celular :”);
setCelular(ent.nextLine());
System.out.println(“Idade :”);
setIdade(Integer.parseInt(ent.nextLine()));
}
}
import java.util.Scanner;
96
salario = sal;
}
}
public Colaborador() {
super();
}
public Colaborador(String matricula, String nome) {
super(matricula, nome);
}
public Colaborador(String nome,int idade) {
super(nome, idade);
}
public Colaborador(String nome, int idade, double salario) {
super(nome, idade);
setSalario(salario);
}
public Colaborador(String matricula, String nome, int codigoCarreira,
double salario) {
super(matricula, nome);
setCodigoCarreira(codigoCarreira);
setSalario(salario);
}
public Colaborador(String matricula, String nome, String celular, int idade) {
super(matricula, nome, celular, idade);
}
public Colaborador(String matricula, String nome, String celular,int idade, int
codigoCarreira, double salario) {
super(matricula, nome, celular, idade);
setCodigoCarreira(codigoCarreira);
setSalario(salario);
}
public void cadastrar(String matricula, String nome, String celular, int idade,
int codigoCarreira, double salario) {
// Reaproveitamento do método cadastrar da superclasse.
super.cadastrar(matricula, nome, celular, idade);
setCodigoCarreira(codigoCarreira);
setSalario(salario);
}
public void imprimir() {
// Reaproveitamento do método imprimir da superclasse.
super.imprimir();
System.out.println(“Código Carreira:” + getCodigoCarreira());
System.out.println(“Salário :” + getSalario());
}
97
public void entrada() {
// Como o Scanner não é um atributo da classe,
// ele deve ser declarado dentro do método em que será utilizado,
// como um objeto auxiliar
Scanner ent = new Scanner(System.in);
// Reaproveitamento do método entrada da superclasse.
super.entrada();
System.out.println(“Código Carreira:”);
setCodigoCarreira(Integer.parseInt(ent.nextLine()));
System.out.println(“Salário :”);
setSalario(Double.parseDouble(ent.nextLine()));
}
}
import java.util.Scanner;
98
public Aluno(String matricula, String nome, int codigoCurso, double cr) {
super(matricula, nome);
setCodigoCurso(codigoCurso);
setCr(cr);
}
public Aluno(String matricula, String nome, int idade, int codigoCurso, double cr) {
super(matricula, nome, idade);
setCodigoCurso(codigoCurso);
setCr(cr);
}
public Aluno(String matricula, String nome, String celular, int idade,
int codigoCurso, double cr) {
super(matricula, nome, celular, idade);
setCodigoCurso(codigoCurso);
setCr(cr);
}
public void cadastrar(String matricula, String nome, String celular, int idade,
int codigoCurso, double cr) {
// Reaproveitamento do método cadastrar da superclasse.
super.cadastrar(matricula, nome, celular, idade);
setCodigoCurso(codigoCurso);
setCr(cr);
}
public void imprimir() {
// Reaproveitamento do método imprimir da superclasse.
super.imprimir();
System.out.println(“Código Curso :” + getCodigoCurso());
System.out.println(“CR :” + getCr());
}
public void entrada() {
// Como o Scanner não é um atributo da classe,
// ele deve ser declarado dentro do método em que será utilizado,
// como um objeto auxiliar
Scanner ent = new Scanner(System.in);
// Reaproveitamento do método entrada da superclasse.
super.entrada();
System.out.println(“Código Curso :”);
setCodigoCurso(Integer.parseInt(ent.nextLine()));
System.out.println(“CR :”);
setCr(Double.parseDouble(ent.nextLine()));
}
}
99
Classe: Professor (subclasse de Colaborador)
import java.util.Scanner;
100
}
public void cadastrar(String matricula, String nome, String celular, int idade,
int codigoCarreira, double salario, String titulacao) {
super.cadastrar(matricula, nome, celular, idade, codigoCarreira,
salario);
setTitulacao(titulacao);
}
public void imprimir() {
// Reaproveitamento do método imprimir da superclasse.
super.imprimir();
System.out.println(“Titulação :” + getTitulacao());
}
public void entrada() {
// Como o Scanner não é um atributo da classe,
// ele deve ser declarado dentro do método em que será utilizado,
// como um objeto auxiliar
Scanner ent = new Scanner(System.in);
// Reaproveitamento do método entrada da superclasse.
super.entrada();
System.out.println(“Titulação :”);
setTitulacao(ent.nextLine());
}
}
Classe: Funcionario (subclasse de Colaborador)
import java.util.Scanner;
101
public Funcionario(String nome, int idade) {
super(nome, idade);
}
public Funcionario(String matricula, String nome, int codigoCarreira,
double salario, String funcao) {
super(matricula, nome, codigoCarreira, salario);
setFuncao(funcao);
}
public Funcionario(String matricula, String nome, String celular, int idade,
int codigoCarreira, double salario, String funcao) {
super(matricula, nome, celular, idade, codigoCarreira, salario);
setFuncao(funcao);
}
public Funcionario(String matricula, String nome, String celular, int idade) {
super(matricula, nome, celular, idade);
}
public Funcionario(String matricula, String nome, String funcao) {
super(matricula, nome);
setFuncao(funcao);
}
public void cadastrar(String matricula, String nome, String celular, int idade,
int codigoCarreira, double salario, String funcao) {
super.cadastrar(matricula, nome, celular, idade);
setFuncao(funcao);
}
public void imprimir() {
// Reaproveitamento do método imprimir da superclasse.
super.imprimir();
System.out.println(“Função :” + getFuncao());
}
public void entrada() {
// Como o Scanner não é um atributo da classe,
// ele deve ser declarado dentro do método em que será utilizado,
// como um objeto auxiliar
Scanner ent = new Scanner(System.in);
// Reaproveitamento do método entrada da superclasse.
super.entrada();
System.out.println(“Função :”);
setFuncao(ent.nextLine());
}
}
102
Classe: AppHeranca (aplicação para os testes)
Notas:
103
atualização da classe Pessoa fará com que os métodos de entrada, imprimir, ca-
dastrar, setters, getters e construtores sejam atualizados no reaproveitamento e na
herança pelas subclasses. Caso seja um atributo comum somente a Professor e
Funcionario, basta atualizar a classe Colaborador. Se a inclusão for específica a al-
guma das três classes originais (Aluno, Professor e Funcionario), basta realizar a
atualização na classe específica.
5. Perceba que foi realizada um sobrescrita nos métodos imprimir e entrada. Isso
permite que não tenhamos códigos duplicados e façamos o reaproveitamento do
método da superclasse, que, se for alterado, fará com que a subclasse seja atuali-
zada automaticamente.
O recurso de reaproveitamento de código foi empregado no exemplo anterior nos
métodos construtores que chamaram para execução da superclasse [super()] e nos
métodos cadastrar( .. ), imprimir() e entrada(), respectivamente com super.cadas-
trar( .. ), super.imprimir() e super.entrada(). Já os métodos imprimir() e entrada() fo-
ram sobrescritos na subclasse, uma vez que possuem o mesmo nome e a mesma
assinatura dos respectivos métodos na superclasse.
MIDIATECA
104
MIDIATECA
105
Encapsulamento de métodos e atributos e a
organização de classes em pacotes
Encapsulamento
O objeto deve se comportar como uma caixa-preta, que realiza determinadas funciona-
lidades, mas que um desenvolvedor que for utilizar a classe em alguma aplicação não
sabe e não precisa saber exatamente como ocorre.
106
Tipos de visibilidade de membros de uma classe:
Omissão
public protected private
(package ou padrão)
Os métodos e
A classe é definida
atributos são
A classe, método como classe de
A classe, método acessíveis pelos
ou atributo é sem- suporte, já que
ou atributo é aces- membros da pró-
pre acessível a to- seus métodos
sível somente por pria classe e pelas
dos os métodos de e atributos são
métodos das clas- suas subclasses
quaisquer outras acessíveis somen-
ses que pertencem (herança), sendo
classes. É o nível te por membros da
ao mesmo pacote também acessíveis
menos rígido de própria classe. É o
(package). por outras classes
encapsulamento. nível mais rígido de
que estejam no
encapsulamento.
mesmo pacote.
public
• A palavra-chave public altera essa visibilidade de forma a ampliá-la, deixando-a sem restrições.
• Uma classe definida como pública pode ser utilizada por qualquer aplicação ou classe em
qualquer pacote. Em Java, uma unidade de compilação (um arquivo-fonte com extensão
.java) pode ter no máximo uma classe pública, cujo nome deve ser o mesmo do arquivo (sem
a extensão). As demais classes na unidade de compilação, não públicas, são consideradas
classes de suporte para a classe pública e têm a visibilidade padrão (pacote).
• Um atributo public de uma classe pode ser diretamente acessado e manipulado por apli-
cações e objetos de outras classes, sem nenhum tipo de restrição. O conjunto de atributos
públicos é visível e de acesso irrestrito.
• Um método public de uma classe pode ser usado por qualquer aplicação e objetos de qual-
quer classe. O conjunto de métodos públicos de uma classe determina o que pode ser feito
com objetos da classe, ou seja, determina o seu comportamento, suas ações.
107
Padrão / Omissão
• Para maior segurança nos dados de um sistema, devemos separar a classe da aplicação das
demais classes.
• Para criar pacotes em seu projeto, clique sobre o projeto com o botão direito do mouse e
escolha New > Package:
108
• Nomes de pacotes podem começar por letras minúsculas:
109
protected
private
Quando um método de uma classe faz referência a outro membro dessa classe para um
objeto específico dessa classe, como o Java assegura que o objeto adequado recebe
referência?
A resposta é que cada objeto tem acesso a uma referência a ele próprio — chamado
de referência this.
Utiliza-se a referência this implicitamente para fazer referências aos membros de uma
classe:
Exemplo
String nome;
public void setNome(String nome) {
this.nome = nome;
}
110
O uso do this permite que:
this.nome = nome;
Importante
Por questões de segurança dos dados dos objetos em uma aplicação, sempre
separe a sua aplicação em um pacote diferente das demais classes, que podem
ser separadas umas das outras em função de suas aplicabilidades.
É comum assegurarmos que os atributos não tenham acesso direto pela apli-
cação, como uma questão de segurança. Também é comum que tenhamos
alguns métodos ocultos (sem visibilidade) por questões de implementação.
Exemplo
package biblioteca;
111
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = verificarNome(nome);
}
public int getIdade() {
return idade;
}
public void setIdade(int idade) {
this.idade = verificarIdade(idade);
}
protected String verificarNome(String nome) {
if(!nome.isEmpty()) {
return nome;
}
else {
return “”;
}
}
protected int verificarIdade(int idade) {
if(idade >=0) {
return idade;
}
else {
return 0;
}
}
}
package biblioteca;
112
return peso;
}
else {
return 0.0;
}
}
}
Notas:
package aplicacao;
import biblioteca.SuperClasse;
import biblioteca.SubClasse;
sp.nome = “Maria”;
}
}
package aplicacao;
import biblioteca.SuperClasse;
113
import biblioteca.SubClasse;
sp.verificarNome(“Maria”);
}
}
package aplicacao;
import biblioteca.SuperClasse;
import biblioteca.SubClasse;
Execução:
Nome: Maria
Idade: 35
Peso: 65.5
Para o objeto sb definido na aplicação, serão exibidos pelo IDE apenas os métodos:
• setNome()
• setIdade();
114
• setPeso();
• getNome();
• getIdade();
• getPeso();
MIDIATECA
MIDIATECA
115
Os conceitos de classes abstratas e interfaces
Modificador static
Atributo Método
Exemplo:
public class MinhaClasse{
public static double meioPI( ) {
public static int idadeMinima = 15;
return Math.PI / 2;
}
Em todas as instâncias da classe, o atributo
}
idadeMinima terá o mesmo valor; caso ele
seja alterado, o novo valor será o mesmo para
Só é necessário importar a classe MinhaClas-
todos os objetos criados.
se e utilizar esse método sem criar o objeto
(instanciar): em qualquer aplicação que im-
porte esta classe: MinhaClasse.meioPI();.
Modificador final
116
Para que não seja permitido
que um método seja redefi-
nido por uma ou mais de
suas subclasses, o progra-
Um atributo final pode ser mador da superclasse pre-
declarado e não ter seu valor cisa impedir explicitamente
inicializado imediatamente, que as subclasses o rede-
mas, após a sua primeira atri- finam e, portanto, alterem
Isso pode restringir muito o
buição, esse valor não poderá o comportamento de um
projeto, então é comum de-
mais ser alterado. método.
clarar apenas um ou poucos
métodos como final. Isso
Exemplo: Exemplo:
permite que a classe ainda
possa ser redefinida, pos-
public final int IDADEMINIMA = 15; public class MinhaClasse{
sibilitando a sobrescrita de
public final double
qualquer método não final.
Para cada instância da classe, meioPI( ) {
o atributo IDADEMINIMA, ao return Math.PI /2;
ser inicializado, não poderá ter }
o seu valor alterado. }
Usar final é uma forma eficaz para restringir a redefinição de alguns métodos de suas
classes, aumentando a segurança da aplicação quando necessário.
Atributo Método
Exemplo:
Exemplo:
117
Classes abstratas
São classes usadas como superclasses e, por não serem completas para representar
um objeto, não devem ser instanciadas, isso em função da caracterização de pelo menos
um método abstrato na classe:
• Pode ocorrer que, ao escrever um método para uma classe, você não saiba como
ele vai ser implementado. Nesse caso, a implementação será feita pela classe que
herdar o método (a classe-filha).
• Pode ocorrer também que você saiba que um determinado método será sobrescri-
to com certeza na classe-filha; então, por que definir sua implementação se ele não
será usado a partir da superclasse?
• Esse método é apenas declarado (definição), mas não implementado (codificado).
Esse conceito determina que é obrigatório que esse método seja implementado na
classe-filha.
• Esse conceito fornece uma regra de obrigatoriedade (regras de negócios) para a
implementação de métodos concretos nas classes-filhas (descendentes).
• Em alguns casos, é comum que não sejam criados objetos a partir da superclasse,
mas ela será responsável por descrever membros (atributos e métodos) que serão
usados por diversas subclasses. A classe Humano, por exemplo, determina uma
série de características similares entre homens e mulheres, mas na prática a aplica-
ção irá criar objetos da classe Homem e da classe Mulher, mas não serão criados
objetos da classe Humano.
ATENÇÃO:
Atributos não podem ser declarados como abstratos, apenas métodos.
118
são chamadas de classes concretas.
• Apresentam o modificador abstract.
• Apresentam apenas a assinatura, seguida de “;”.
• Não possuem corpo.
Exemplo:
Uma classe abstrata serve para modelar objetos que possuam características seme-
lhantes, mas, ainda assim, tenham comportamento distinto para ações semelhantes.
Exemplo
Exemplo prático:
package biblioteca;
119
}
public String getNome() {
return this.nome;
}
public String getSexo() {
return this.sexo;
}
public int getIdade() {
return this.idade;
}
public double getPeso() {
return this.peso;
}
public double getAltura() {
return this.altura;
}
public abstract String amamentar();
}
package biblioteca;
120
public double getPeitoral() {
return this.peitoral;
}
public String amamentar() {
return “Homens usam mamadeiras”;
}
}
package biblioteca;
121
Classe: Manjar-principal (pacote: aplicacao)
package aplicacao;
122
Classes abstratas podem ser instanciadas em situações especiais:
se for usado um construtor de uma subclasse, desde que esta contenha a implementa-
ção dos métodos abstratos definidos nela.
Exemplo
Execução:
Interfaces
Uma interface Java é uma classe abstrata em que todos os seus métodos são abstract
e public e seus atributos são static e final implicitamente.
123
Exemplo
Uma interface estabelece um molde a ser obedecido pelas classes que irão usá-la. Força
que uma classe, ao implementar uma interface, tenha que oferecer obrigatoriamente to-
das as funcionalidades especificadas por esta, assim como os seus atributos de classe.
Exemplo
package biblioteca;
void imprimir();
void entrada();
package biblioteca;
124
// Somente os métodos getters
// como os atributos em uma interface são final,
// não poderão ser alterados, ou seja, não teremos
// os métodos setters
public int getPotenciaMaxima( );
public int getPotenciaMinima( );
package biblioteca;
package biblioteca;
import java.util.Scanner;
125
}
public void setModelo( String modelo ) {
this.modelo = modelo;
}
public int getVolume() {
return volume;
}
public void setVolume( int volume ) {
this.volume = volume;
}
public int getPotencia() {
return potencia;
}
public void setPotencia( int potencia ) {
this.potencia = potencia;
}
public Fogao( ) { }
public Fogao( String marca, String modelo ) {
this.marca = marca;
this.modelo = modelo;
}
public Fogao( int volume, int potencia ) {
this.volume = volume;
this.potencia = potencia;
}
public Fogao( String marca, String modelo, int volume, int potencia ) {
this.marca = marca;
this.modelo = modelo;
this.volume = volume;
this.potencia = potencia;
}
public void cadastrar( String marca, String modelo, int volume, int potencia ) {
this.marca = marca;
this.modelo = modelo;
this.volume = volume;
this.potencia = potencia;
}
public void imprimir() {
System.out.println(“Marca :” + getMarca());
System.out.println(“Modelo :” + getModelo());
System.out.println(“Volume :” + getVolume());
System.out.println(“Potência:” + getVolume());
}
126
public void entrada() {
Scanner ent = new Scanner(System.in);
System.out.println(“Marca :”);
setMarca(ent.nextLine());
System.out.println(“Modelo :”);
setModelo(ent.nextLine());
System.out.println(“Volume :”);
setVolume(Integer.parseInt(ent.nextLine()));
System.out.println(“Potência:”);
setVolume(Integer.parseInt(ent.nextLine()));
}
public int getPotenciaMaxima() {
return POTENCIAMAXIMA;
}
public int getPotenciaMinima() {
return POTENCIAMINIMA;
}
public void assar(int potencia) {
setPotencia(potencia);
System.out.println(“Forno assando com potencia=” + getPotencia());
}
public void aquecer(int potencia) {
setPotencia(potencia);
System.out.println(“Forno aquecendo com potencia=” + getPotencia());
}
public void desligar() {
System.out.println(“Desligar Forno.”);
}
public void metodoX(int x) {
System.out.println(“Valor de X: “ + x);
}
}
package aplicacao;
import biblioteca.Forno;
127
Forno f = new Forno(“GE”, “f505”, 60, 120);
f.assar(200);
f.desligar();
System.out.println();
}
}
Execução:
Notas:
1. A interface Interface_De_Controle deve ser identificada tal como como uma clas-
se (ou seja, seu identificador deve começar por letras maiúsculas) e determina as
regras de negócio a serem implementadas pelas classes que implementarem a in-
terface.
2. A classe Fogao implementa as interfaces Regras e Interface_De_Controle — isso
faz com tenha acesso aos atributos das interfaces (static e final) — e deve imple-
mentar todos os métodos definidos nas interfaces, além do metodoX(), que é um
método abstrato da superclasse abstrata.
3. A aplicação utiliza normalmente a classe Forno, independentemente se esta utili-
za classes abstratas ou interfaces.
ATENÇÂO:
128
• Podemos utilizar em conjunto a herança, classes abstratas e interfaces:
MIDIATECA
MIDIATECA
129
MIDIATECA
NA PRÁTICA
Ao desenvolvermos um sistema, não basta que ele funcione, mas também que
tenha sido desenvolvido de forma que possa ser reaproveitado e que seja de
fácil manutenção. Para isso, precisamos saber aplicar corretamente os concei-
tos de orientação a objetos. Para uma melhor compreensão e visão da impor-
tância de trabalhar com herança, classes abstratas e interfaces, implemente
os programas apresentados nos exemplos práticos e analise os códigos e os
resultados obtidos.
130
Resumo da Unidade 3
Nesta unidade, você conheceu e aplicou na prática alguns conceitos avançados da pro-
gramação orientada a objetos, entre eles a herança, que permite um melhor reaprovei-
tamento de código, implicando, ainda, uma maior facilidade na manutenção do sistema.
Conheceu e aplicou na prática também um conceito voltado à preparação do sistema
para atender às chamadas “regras de negócio”, tão importantes para satisfazer as expec-
tativas do cliente no desenvolvimento do sistema.
CONCEITO
131
Referências
DEITEL, P. Java: como programar. 10. ed. São Paulo: Pearson Education do Brasil, 2017.
Biblioteca Virtual.
SCHILDT, H. Java para iniciantes: crie, compile e execute programas Java rapidamente.
6. ed. Porto Alegre: Bookman, 2015. Minha Biblioteca.
132
UNIDADE 4
OBJETIVO
134
Estruturas estáticas: vetores e matrizes de
tipos básicos
Vetores também são conhecidos como variáveis indexadas, uma vez que são variáveis
com o mesmo nome, mas com índices diferentes.
Vetores
135
100 elementos possui índice 99 para o último elemento, uma vez que o índice
sempre começa por 0 (zero).
Vetores de tipos básicos não requerem muitos cuidados, mas você verá que vetores de
objetos requerem alguns cuidados.
Primeiro 0 1 2 3 4 5 6 7 8 9 Índices
índice
Se tentarmos acessar um elemento fora do escopo do vetor, é gerada uma exceção indi-
cando que o uso de uma posição inválida foi referenciada. A exceção gerada é:
java.lang.OutOfBoundException
Podemos definir os valores dos elementos de um vetor junto com a sua declaração.
136
Para a criação de um vetor com as notas de 10 alunos de uma sala de aula, vamos usar:
float nota[] = {10.0f, 5.0f, 6.6f, 8.0f, 7.0f, 7.8f, 8.4f, 4.2f, 1.8f, 6.4f };
A quantidade de elementos não precisa ser definida quando você determina os valores
dos elementos.
nota[0] 10.0 nota[1] 5.0 nota[2] 6.6 nota[3] 8.0 nota[4] 7.0
nota[5] 7.8 nota[6] 8.4 nota[7] 4.2 nota[8] 1.8 nota[9] 6.4
// Binários
byte vbin[] = new byte[10];
vbin[0] = 0;
vbin[9] = 0;
// Inteiro curto
short vshort[] = new short[20];
vshort[0] = 0;
vshort[19] = 0;
// Inteiro
int vint[] = new int[30];
vint[0] = 0;
vint[29] = 0;
// Inteiro longo
long vlong[] = new long[40];
vlong[0] = 0;
vlong[39] = 0;
// Real de simples precisão
float vfloat[] = new float[20];
vfloat[0] = 0;
vfloat[19] = 0;
// Real de dupla precisão
double vdouble[] = new double[20];
vdouble[0] = 0;
vdouble[19] = 0;
// Caracteres
char vchar[] = new char[26];
137
vchar[0] = ‘A’;
vchar[25] = ‘Z’;
// Lógicos
boolean vbool[] = new boolean[10];
vbool[0] = false;
vbool[9] = true;
// String (texto)
String vstring[] = new String[100];
vstring[0] = “André”;
vstring[99] = “Zandini”;
Vetores podem ter os seus elementos definidos por meio de uma expressão aritmética.
A seguir o exemplo cria um vetor de double com 12 elementos:
// Declaração do vetor:
double fracoes[] = new double[12];
// Preenchimento do vetor
for (int i=0; i<12; i++) {
// Se for apenas i, será gerada uma exceção por tentativa de divisão por zero
fracoes[i] = 1 / (i + 1);
}
// Exibição do conteúdo do vetor
for (int i=0; i<12; i++) {
System.out.println(“fracoes[“+ i + “] = “ + fracoes[i]);
}
Importante
Conforme colocado por Deitel (2017), “declarar múltiplas variáveis em uma úni-
ca declaração pode levar a erros sutis”.
138
Entretanto, se apenas a destina-se a ser uma variável de array, e b e c, variá-
veis int individuais, então essa declaração é incorreta — a declaração int a[],
b, c; alcançaria o resultado desejado (DEITEL, 2017, p. 194).
O exemplo a seguir cria um vetor de tipos básicos do tipo String, que realiza a entrada de
Exemplo
Exemplo prático:
Classe: Vetores
import java.util.Scanner;
// Declaração do vetor
String nomes[] = new String[5];
// Preenchimento do vetor
for (int i = 0; i < 5; i++) {
System.out.println(“Digite um nome: “);
nomes[i] = ent.nextLine();
}
System.out.println();// Pula uma linha
// Exibição do conteúdo do vetor
for (int i = 0; i < 5; i++) {
System.out.println(nomes[i]);
}
}
}
139
Resultados:
Digite um nome:
João
Digite um nome:
Marcela
Digite um nome:
Maria
Digite um nome:
Pedro
André
João
Marcela
Maria
Pedro
Notas:
System.out.println(nomes);
[Ljava.lang.String;@28d93b30
140
Seguem alguns exemplos de vetores com valores predeterminados:
A forma mais comum de uso de vetores é por meio da entrada de dados para armazena-
mento e posterior acesso aos valores armazenados. Vamos analisar o exemplo a seguir, para
resolver o problema inicial, apresentando a quantidade de alunos de uma turma com 100
estudantes, e saber quantos alunos estão com média igual ou superior à média da turma.
Exemplo
Exemplo prático:
Classe: Vetores
import java.util.Scanner;
// Declaração do vetor
int totalAlunos = 100;// Você pode alterar a quantidade
int contaAlunosMedia=0;
double medias[] = new double[totalAlunos];
double somaMedias=0, mediaTurma=0;
141
// Preenchimento do vetor com as médias dos alunos
for (int i = 0; i < medias.length; i++) {
System.out.println(“Digite a média do aluno[“ + (i+1) +”]:” );
medias[i] = Double.parseDouble(ent.nextLine());
somaMedias += medias[i];
}
mediaTurma = somaMedias / totalAlunos;
// Conta quantos alunos estão com média igual ou superior
// à média da turma
for (int i = 0; i < medias.length; i++) {
if(medias[i]>=mediaTurma) {
contaAlunosMedia ++;
}
}
System.out.println();// Pula uma linha
// Exibe a média da turma e a quantidade de alunos
// Com média igual ou superior à média da turma
System.out.printf(“Média da turma %.2f :”, mediaTurma);
System.out.println();// Pula uma linha
System.out.print(“Alunos com média igual ou superior a média da turma:”);
System.out.printf(“ %d “, contaAlunosMedia);
}
}
Resultados:
142
Notas:
int totalAlunos = 0;
int contaAlunosMedia=0;
System.out.println(“Quantos alunos a turma possui?”);
totalAlunos = Integer.parseInt(ent.nextLine());
double medias[] = new double[totalAlunos];
Matrizes
Matrizes são como os vetores, mas, enquanto um vetor possui apenas uma dimensão
(um índice), as matrizes possuem duas dimensões e, por consequência, dois índices.
Matrizes são importantes para o armazenamento de conjuntos de dados para realização
de operações matemáticas, assim como para o armazenamento de conjuntos de dados.
143
Podemos usar uma matriz para armazenar um conjunto de notas de um grupo de alunos.
O grupo de alunos pode determinar a quantidade de linhas da matriz, e a quantidade de
notas, o número de colunas.
Características:
Para criar uma matriz contendo 10 linhas e 10 colunas de inteiros, deve-se escrever:
1 2 3
Declaração da matriz em Java:
4 5 6
int matriz[][] = new int[3][3];
7 8 9
Podemos definir os valores dos elementos de uma matriz junto com a sua declaração,
criando a matriz com valores inteiros, com a seguinte sintaxe:
int matriz[][] = { {0, 1, 2}, {1, 11, 12}, {2, 21, 22} };
144
0 1 2 O resultado é determinado pelas linhas, cada conjunto
1 11 12 entre chaves e as colunas, com os elementos dentro de
2 21 22 cada linha.
// Binários
byte mbin[][] = new byte[10][30];
mbin[0][0] = 0;
mbin[9][29] = 0;
// Inteiro curto
short mshort[][] = new short[20][30];
mshort[0][0] = 0;
mshort[19][29] = 0;
// Inteiro
int mint[][] = new int[30][30];
mint[0][0] = 0;
mint[29][29] = 0;
// Inteiro longo
long mlong[][] = new long[40][30];
mlong[0][0] = 0;
mlong[39][29] = 0;
// Real de simples precisão
float mfloat[][] = new float[20][20];
mfloat[0][0] = 0;
mfloat[19][19] = 0;
// Real de dupla precisão
double mdouble[][] = new double[20][1000];
mdouble[0][0] = 0;
mdouble[19][999] = 0;
// Caracteres
char mchar[][] = new char[30][26];
mchar[0][0] = ‘a’;
mchar[29][25] = ‘Z’;
// Lógicos
boolean mbool[][] = new boolean[10][40];
mbool[0][0] = false;
mbool[9][39] = true;
// String (texto)
String mstring[][] = new String[100][5];
mstring[0][0] = “André”;
mstring[99][4] = “Zandini”;
145
Declaração de estruturas multidimensionais:
O Java permite, ainda, a criação de estruturas com mais dimensões, tal como um cubo
de dados ou com mais dimensões.
Região 1
Região 2
Região 3
Região 4
Produto 3
Região 5 Produto 2
Produto 1
Dia 1 Dia 2 Dia 3 Dia 4
Fonte: docs.microsoft.com/pt-br.
Um cubo de dados pode armazenar pares de dados, tal como código do produto e sua
quantidade, mas com um dado a mais, fazendo referência à data em que determinada
quantidade do produto foi vendida. Com um cubo de dados, é possível criar gráficos ilus-
trativos com a evolução das vendas ao longo do tempo.
MIDIATECA
146
MIDIATECA
147
Criação de vetores de objetos e a organiza-
ção em memória
Isso indica que não temos uma referência válida ainda nessa posição, sendo necessária
a instanciação do objeto. Se for feita uma referência a um elemento que ainda esteja
com o valor null, ocorrerá a exceção: java.lang.NullPointerException, e isso indica que
foi feita uma tentativa de acesso a um objeto inválido. Dessa forma, vetores e matrizes
de objetos requerem um cuidado maior para a sua criação e uso, mas são muito interes-
santes para tratar conjuntos de objetos em sistemas computacionais.
Você pode criar vetores e matrizes de qualquer tipo de objeto, mas sempre será necessá-
rio instanciar (criar) o objeto antes de usá-lo.
Um tipo String é também um objeto; dessa forma, podemos trabalhar esse tipo também
como um objeto:
// Declaração do vetor
String valores[] = new String[5];
// Preenchimento do vetor
valores[0] = new String(“Zero”);
valores[1] = new String(“Um”);
valores[2] = new String(“Dois”);
valores[3] = new String(“Três”);
valores[4] = new String(“Quatro”);
148
Declaração de vetores e matrizes de objetos:
Vetores de objetos
Observação: a declaração do vetor não instancia os objetos que são elementos do vetor.
Exemplo
Exemplo prático:
// Declaração do vetor
Double valores[] = new Double[15];
// Preenchimento do vetor
for (int i=0; i<15; i++) {
// Cada elemento do vetor é instanciado (criado):
valores[i] = new Double(i);
}
Observe que foi necessário instanciar o objeto, uma vez que double é um tipo bási-
co, e Double é um objeto.
149
Matrizes de objetos
Exemplo
Exemplo prático:
package classes;
import java.util.Scanner;
150
public String getModelo() {
return modelo;
}
public Geladeira() { }
151
public Geladeira(String modelo, int capacidade, double preco) {
setModelo(modelo);
setCapacidade(capacidade);
setPreco(preco);
}
package classes;
import java.util.Scanner;
152
public void setProcessador(String processador) {
if(!processador.isEmpty()){
this.processador = processador;
}
}
public int getQuantidadeMemoria() {
return quantidadeMemoria;
}
public void setQuantidadeMemoria(int quantidadeMemoria) {
if(quantidadeMemoria>0) {
this.quantidadeMemoria = quantidadeMemoria;
}
}
public double getValor() {
return valor;
}
public void setValor(double valor) {
if(valor>0) {
this.valor = valor;
}
}
public Servidor() { }
153
public void cadastrar(String processador,int quantidadeMemoria, double valor) {
setProcessador( processador );
setQuantidadeMemoria( quantidadeMemoria );
setValor( valor );
}
import java.util.Scanner;
154
}
// Geladeiras criadas:
for (int i = 0; i < vetGeladeiras.length; i++) {
// Exibe os dados de cada Geladeira do vetor
vetGeladeiras[i].imprimir();
}
// Declaração da matriz de Servidores com 16 elementos
Servidor matServidores[][] = new Servidor[4][4];
// O atributo length de uma matriz, sem o índice da coluna,
// indica o número de linhas da matriz
for (int i = 0; i < matServidores.length; i++) {
// O atributo length de uma matriz, com a indicação de uma linha,
// indica o número de colunas da matriz
for (int j = 0; j < matServidores[0].length; j++) {
// O mais importante:
// você não pode se esquecer que deve ser criado
// cada objeto Servidor da matriz, antes de usá-lo
matServidores[i][j] = new Servidor();
// Você pode usar qualquer método visível do objeto
// Você deve apenas indicar o índice do elemento
matServidores[i][j].entradaDados();
}
}
// Servidores criados:
for (int i = 0; i < matServidores.length; i++) {
for (int j = 0; j < matServidores[0].length; j++) {
matServidores[i][j].imprimir(); // Exibe os dados de cada Servidor
}
}
}
}
155
Notas:
MIDIATECA
MIDIATECA
156
Aplicação do tratamento de exceções em
vetores e matrizes
Dessa forma, tentar acessar um elemento inexistente gerará uma exceção do tipo java.
lang.OutOfBoundException, e isso fará com que a aplicação se encerre.
Outra causa de exceções em nossas aplicações é a não instanciação dos objetos perten-
centes ao vetor ou matriz. Como a declaração dessas estruturas apenas determina o tipo
e o tamanho, quando trabalhamos com objetos, devemos ter em mente que eles preci-
sam ser instanciados para poderem ser usados. Caso contrário, teremos o lançamento
de uma exceção do tipo java.lang.NullPointerException, que também é uma causa de
encerramento abrupto da aplicação.
O tratamento de exceções em Java é feito por meio de uma estrutura determinada pelo
conjunto try / catch / finally, e devemos trabalhar com essa estrutura para evitar que
nossas aplicações gerem exceções ao usarmos vetores e matrizes.
157
Características do tratamento de exceções:
Uma exceção é um erro que pode ser tratado em tempo de execução e permite que a
aplicação continue apesar do erro. Esse erro pode ser tratado por meio de avisos ao
usuário ou pela execução do código relativo ao tratamento.
Utilizamos algumas palavras reservadas para esse tratamento, são elas: try, catch,
finally, throw e throws.
Conceitos:
158
Uma exceção em Java é um sinal que alguma condição excepcional aconteceu.
Exemplos:
159
Exemplo
Exemplo prático:
package aplicacoes;
//Importa todas as classes do pacote classes
import classes.*;
import java.util.Scanner;
Resolução 1:
160
Valor :
1
Processador :
2
Quantidade Memória:
2
Valor :
2
Processador :
3
Quantidade Memória:
3
Valor :
3
Qual é o índice do elemento que você quer exibir?
2
Processador : 3
Quantidade Memória: 3
Valor : 3.0
Resolução 2:
161
Qual é o índice do elemento que você quer exibir?
3
Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: 3
at aplicacoes.AppExcecoes1.main(AppExcecoes1.java:26)
Notas:
1. No primeiro teste, foi criado um vetor de três elementos, e este foi preenchido
normalmente.
2. No momento da escolha do elemento, foi escolhido o elemento de índice 2, que é
existente e não gerou uma exceção.
3. Já no segundo exemplo, também foram criados três elementos, mas, ao ser so-
licitado o índice do elemento, foi informado o total de elementos, 3 (três), que não é
um índice válido, lançando a exceção.
Para evitar tal problema, podemos então proteger nosso vetor com um tratamento de
exceções para a situação:
Exemplo
Exemplo prático:
package aplicacoes;
import java.util.Scanner;
162
int qtdElementos = 0;
int elemento;
// Variável para determinar o encerramento da aplicação
boolean continuar = true;
// Definição da quantidade de elementos do vetor
System.out.println(“Quantos elementos do tipo Servidor no vetor?”);
qtdElementos = Integer.parseInt(ent.nextLine());
// Declaração do vetor
Servidor vetServ[] = new Servidor[qtdElementos];
Resolução:
163
Valor :
1
Processador :
2
Quantidade Memória:
2
Valor :
2
Processador :
3
Quantidade Memória:
3
Valor :
3
Qual é o índice do elemento que você quer exibir?
3
Você escolheu um elemento inexistente do vetor.
Tente novamente!
Qual é o índice do elemento que você quer exibir?
2
Processador : 3
Quantidade Memória: 3
Valor : 3.0
Notas:
1. No teste, foi criado um vetor de três elementos, e este foi preenchido normalmente.
2. No momento da escolha do elemento, foi escolhido o elemento de índice 3, que é
inexistente e lançou uma exceção.
3. Como a aplicação está protegida, foi exibida uma mensagem ao usuário, mas a
aplicação não encerrou.
4. Para efeito didático, foi incluída uma repetição que fez com que fosse solicitado
novamente o índice do elemento; uma vez sendo inserido um índice válido, a aplica-
ção exibiu corretamente os dados do elemento e encerrou normalmente.
164
índice do elemento que será usado no preenchimento de dados — porém, elementos não
instanciados lançarão uma exceção.
Exemplo
Exemplo prático:
package aplicacoes;
import java.util.Scanner;
165
continuar = true;
// Repetição até apresentar um elemento válido
do {
System.out.println(“Qual é o índice do elemento que você quer exibir?”);
elemento = Integer.parseInt(ent.nextLine());
// Exibe o elemento
vetServ[elemento].imprimir();
continuar = false;
} while (continuar);
}
}
Resolução:
166
Notas:
Como temos uma nova exceção, o trecho de proteção terá mais uma cláusula catch, para
atender a essa nova demanda. Lembre-se de que podemos ter várias cláusulas catch
para cada conjunto try.
Exemplo
Exemplo prático:
package aplicacoes;
import java.util.Scanner;
167
// Declaração do vetor
Servidor vetServ[] = new Servidor[qtdElementos];
// Determinação do elemento a ser preenchido
do {
// Criação dos objetos e preenchimento do vetor
System.out.println(“Qual é o índice do elemento que você quer preencher?”);
System.out.println(“Use -1 para encerrar!”);
int i = Integer.parseInt(ent.nextLine());
if (i != -1) {
vetServ[i] = new Servidor();
vetServ[i].entradaDados();
} else {
continuar = false;
}
} while (continuar);
continuar = true;
// Repetição até apresentar um elemento válido
do {
// Determinação do elemento a ser exibido, com proteção
try {
System.out.println(“Qual é o índice do elemento que você quer exibir?”);
elemento = Integer.parseInt(ent.nextLine());
// Exibe o elemento
vetServ[elemento].imprimir();
continuar = false;
} catch (ArrayIndexOutOfBoundsException ex1) {
System.out.println(“Você escolheu um elemento inexistente do vetor.”);
System.out.println(“Tente novamente!”);
} catch (NullPointerException ex2) {
System.out.println(“Você escolheu um elemento não instanciado do vetor.”);
System.out.println(“Tente novamente!”);
} catch (Exception ex3) {
System.out.println(“Alguma outra exceção ocorreu!”);
}
} while (continuar);
}
}
Resolução:
168
Processador :
1
Quantidade Memória:
1
Valor :
1
Qual é o índice do elemento que você quer preencher?
Use -1 para encerrar!
2
Processador :
3
Quantidade Memória:
3
Valor :
3
Qual é o índice do elemento que você quer preencher?
Use -1 para encerrar!
-1
Qual é o índice do elemento que você quer exibir?
1
Você escolheu um elemento não instanciado do vetor.
Tente novamente!
Qual é o índice do elemento que você quer exibir?
Notas:
Podemos observar que, com a aplicação protegida, o usuário tanto pode escolher um
índice de elemento inexistente como tentar usar um elemento não instanciado que a
169
aplicação não irá encerrar. O uso do tratamento de exceções é mais extenso, mas aqui
fizemos o seu uso para a proteção de vetores — o uso com matrizes é análogo a este,
conforme visto anteriormente.
MIDIATECA
MIDIATECA
NA PRÁTICA
Quando estamos executando uma aplicação, uma exceção pode ser lançada,
ou seja, um evento inesperado pode ocorrer. Uma exceção pode ser lançada
a partir de erros de lógica ou mesmo por ocasião de problemas de hardware
ou de recursos da máquina virtual Java. Como exemplo, ao desenvolvermos
uma calculadora, por mais simples que pareça, não podemos esquecer de que
não existe divisão por zero. Imagine que o usuário tente realizar uma divisão
por zero: uma exceção será disparada, e como consequência teremos a inter-
rupção do programa. Sendo assim, durante o desenvolvimento da aplicação,
precisamos aplicar o conceito de tratamento de exceções, visando identificar e
tratar uma exceção, de forma que o programa continue executando.
170
Resumo da Unidade 4
Nesta unidade, você pôde compreender como trabalhar com vetores e matrizes, além
de aplicar na prática esse conhecimento. Foram abordados os conceitos de vetores e
matrizes para os tipos básicos e para objetos, aumentando consideravelmente as apli-
cações desses recursos no desenvolvimento de nossos projetos na linguagem Java. O
tratamento de exceções no uso de vetores e matrizes também foi abordado de forma
prática em nossos exemplos.
CONCEITO
171
Referências
DEITEL, P. Java: como programar. 10. ed. São Paulo: Pearson Education do Brasil, 2017.
p. 194. Biblioteca Virtual.
SCHILDT, H. Java para iniciantes: crie, compile e execute programas Java rapidamente.
6. ed. Porto Alegre: Bookman, 2015. Minha Biblioteca.
172