0% acharam este documento útil (0 voto)
10 visualizações145 páginas

Programaçao de Sistemas

Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
10 visualizações145 páginas

Programaçao de Sistemas

Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
Você está na página 1/ 145

JANE TAVARES ALVAREZ DA SILVA

Programação de Sistemas

1ª Edição

Brasília/DF - 2022
Autores
Jane Tavares Alvarez da Silva

Produção
Equipe Técnica de Avaliação, Revisão Linguística e
Editoração
Sumário
Organização do Livro Didático....................................................................................................................................... 4

Introdução.............................................................................................................................................................................. 6

Capítulo 1
Introdução à linguagem de programação............................................................................................................ 7

Capítulo 2
Comandos da linguagem Java.................................................................................................................................33

Capítulo 3
Conceitos e Implementação usando Orientação a Objetos.......................................................................... 61

Capítulo 4
Classes e objetos: uma visão mais aprofundada..............................................................................................92

Capítulo 5
Tratamento de exceções......................................................................................................................................... 125

Capítulo 6
Coleções de objetos................................................................................................................................................. 137

Referências ...................................................................................................................................................................... 145


Organização do Livro Didático
Para facilitar seu estudo, os conteúdos são organizados em capítulos, de forma didática,
objetiva e coerente. Eles serão abordados por meio de textos básicos, com questões para
reflexão, entre outros recursos editoriais que visam tornar sua leitura mais agradável. Ao final,
serão indicadas, também, fontes de consulta para aprofundar seus estudos com leituras e
pesquisas complementares.

A seguir, apresentamos uma breve descrição dos ícones utilizados na organização do Livro
Didático.

Atenção

Chamadas para alertar detalhes/tópicos importantes que contribuam para a


síntese/conclusão do assunto abordado.

Cuidado

Importante para diferenciar ideias e/ou conceitos, assim como ressaltar


para o aluno noções que usualmente são objeto de dúvida ou entendimento
equivocado.

Importante

Indicado para ressaltar trechos importantes do texto.

Observe a Lei

Conjunto de normas que dispõem sobre determinada matéria, ou seja, ela é


origem, a fonte primária sobre um determinado assunto.

Para refletir

Questões inseridas no decorrer do estudo a fim de que o aluno faça uma pausa
e reflita sobre o conteúdo estudado ou temas que o ajudem em seu raciocínio.
É importante que ele verifique seus conhecimentos, suas experiências e seus
sentimentos. As reflexões são o ponto de partida para a construção de suas
conclusões.

4
Organização do Livro Didático

Provocação

Textos que buscam instigar o aluno a refletir sobre determinado assunto antes
mesmo de iniciar sua leitura ou após algum trecho pertinente para o autor
conteudista.

Saiba mais

Informações complementares para elucidar a construção das


sínteses/conclusões sobre o assunto abordado.

Gotas de Conhecimento

Partes pequenas de informações, concisas e claras. Na literatura há outras


terminologias para esse termo, como: microlearning, pílulas de conhecimento,
cápsulas de conhecimento etc.

Sintetizando

Trecho que busca resumir informações relevantes do conteúdo, facilitando o


entendimento pelo aluno sobre trechos mais complexos.

Sugestão de estudo complementar

Sugestões de leituras adicionais, filmes e sites para aprofundamento do estudo,


discussões em fóruns ou encontros presenciais quando for o caso.

Posicionamento do autor

Importante para diferenciar ideias e/ou conceitos, assim como ressaltar


para o aluno noções que usualmente são objeto de dúvida ou entendimento
equivocado.

5
Introdução
Este Livro Didático fornece uma diretriz sólida para o estudo de vários tópicos relacionados
à linguagem de programação Java, incluindo conceitos importantes de Orientação a
Objetos, tais como herança e polimorfismo.

Ao longo dos seus seis capítulos, este Livro Didático tenta motivar o estudo da disciplina
Programação de Sistemas, apresentando vários conceitos, exemplos variados, além de
programas na linguagem de programação Java que conjuguem teoria e prática, permitindo
assim, que o leitor construa uma base consistente para a programação de sistemas de
computador.

O primeiro capítulo trata das características da linguagem e de conceitos básicos. Já os


demais capítulos levam o leitor a fazer uma imersão maior na parte prática da linguagem
juntamente com a aplicação dos conceitos de Orientação a Objetos.

Objetivos

» Compreender os conceitos da linguagem de programação Java.

» Construir programas na linguagem de programação Java usando Orientação a


Objetos.

» Identificar o melhor caminho na programação para a solução de um problema.

6
CAPÍTULO
INTRODUÇÃO À LINGUAGEM DE
PROGRAMAÇÃO 1
Introdução ao Capítulo

Este primeiro capítulo abordará alguns dos principais conceitos relativos à linguagem de
programação Java, bem como sua sintaxe, através do estudo dos tipos de dados, entrada/saída
de dados e operadores, permitindo assim, que os primeiros programas sejam escritos.

Algumas seções deste capítulo somente receberão o devido formalismo em outro momento,
quando forem estudados os conceitos de orientação a objetos.

Objetivos do Capítulo

» Identificar as características da linguagem de programação Java.

» Apresentar o ambiente de desenvolvimento.

» Escrever os primeiros programas na linguagem de programação Java.

1.1 Características da linguagem Java

A linguagem Java é uma linguagem Orientada a Objetos (OO) e foi desenvolvida na década
de 1990 por James Gosling da Sun Microsystems.

Além da característica de ser uma linguagem orientada a objetos, a linguagem Java tem
outras características, como, por exemplo:

» Portabilidade, ou seja, independe da plataforma. O lema é “Write once, run


everywhere”. Traduzindo: Escreva uma vez e rode (execute) em qualquer lugar.
Isso significa que um programa escrito na linguagem Java pode ser executado em
computadores com diferentes sistemas operacionais, como, por exemplo, Windows
ou Linux.

7
CAPÍTULO 1 • Introdução à linguagem de programação

» Grande diversidade disponível de bibliotecas de classes. Ou seja, existe muito recurso


pronto, evitando, assim, a necessidade de escrevermos o que já foi programado na
linguagem.

» Sintaxe simples, se comparada com outras linguagens OO.

Todo programa em Java deve ter um método main que determina o início da execução do
programa. Não se preocupe em entender tudo agora sobre o programa do exemplo, o que é
classe e o que é o método main.

Exemplo:

/* Arquivo: PrimeiroProg.java */

public class PrimeiroProg {

public static void main(String [] args) {

System.out.println(“Meu primeiro programa.”);

} // fim do método main

} // fim da classe PrimeiroProg

Importante

É importante notar que:

» O método main deve estar dentro de uma classe pública, cujo nome é igual ao nome do arquivo .java.

» O nome do arquivo com código em java tem extensão .java.

Apesar de estar apenas começando seus estudos em Java, o que você espera que o programa
anterior faça ao executar? O programa irá imprimir ou fazer o seguinte print ou impressão
na tela do computador: Meu primeiro programa.

Todo programa ou código Java deve ficar dentro de uma classe delimitada por chaves e
para definir uma classe, usamos uma palavra reservada para esse fim, que é a palavra class.

Saiba mais

Os comentários seguem o mesmo padrão de outras linguagens, a saber, as linguagens C e C++:

/* e */ para comentários multilinhas

// para comentários em uma linha

Os comentários são uma boa prática de programação e servem como documentação do programa, orientando quem for ler
ou fazer a manutenção no programa.

8
Introdução à linguagem de programação • CAPÍTULO 1

1.2 Plataforma Java

O termo plataforma normalmente é usado para designar um conjunto:

Hardware + Sistema Operacional

Nas linguagens compiladas que geram código nativo (binário), é necessário um processo
de compilação para cada plataforma, pois o código gerado só executa naquela plataforma
específica.

A plataforma Java é definida apenas em software e tem dois componentes principais:

» Máquina Virtual Java (JVM – Java Virtual Machine)

» Conjunto de bibliotecas que implementam funções úteis (API Java)

Diferentemente das linguagens que são compiladas para código nativo, a linguagem Java é
compilada para bytecode (.class ou .jar) que é executado por uma JVM (Java Virtual Machine).

Saiba mais

API significa Application Programming Interface. Traduzindo: Interface de Programação de Aplicações.

A API Java oferece uma rica coleção de classes e métodos para, por exemplo:

» realizar cálculos matemáticos comuns;

» manipular sequências de caracteres (strings);

» verificar e tratar erros.

Figura 1. Plataforma Java.

Fonte: elaborada pela autora.

9
CAPÍTULO 1 • Introdução à linguagem de programação

Essa camada extra entre o Sistema Operacional e o programa permite que este seja
executado em diversas plataformas, sem a necessidade de alteração ou recompilação
(portabilidade). Na Figura 1, o mesmo programa teste.java (observe a extensão .java)
poderá ser executado, sem qualquer ajuste ou mudança, em um ambiente com Linux ou em
um ambiente com Windows 10.

Saiba mais

O compilador é um programa tradutor. No caso da linguagem de programação Java, o compilador é o javac.

Simplificadamente, o papel de qualquer compilador é traduzir o programa escrito em alguma linguagem de alto nível em
linguagem de máquina. As linguagens de alto nível têm instruções que se parecem, em geral, com o inglês do dia a dia. Já a
linguagem de máquina consiste em sequências de zeros e uns.

Veja o modelo de compilação e execução na figura 2. Note que o programa Java (arquivo
de extensão .java) é compilado para bytecode, gerando um arquivo com extensão .class.
Esse arquivo contém o código executável que independe da plataforma. Para executar esse
código é necessário uma máquina virtual (JVM), que irá traduzir e executar o bytecode no
ambiente desejado, seja ele Linux, Windows© ou MacOS©.

Figura 2. Modelo de compilação e execução.

Fonte adaptada: https://www.shutterstock.com/pt/image-photo/kazan-russia-april-11-2017-set-645421069.

Importante

Desenvolvedores Java devem fazer download do Java SE Development Kit (JDK), da Plataforma Java, no site https://www.
oracle.com/java/.

JDK é o Kit de Desenvolvimento Java para standard edition (SE) ou edição padrão. Tal kit inclui o ambiente de execução, que
é o JRE (Java Runtime Environment), além de ferramentas para desenvolvimento, debugging (depuração) e monitoramento
das aplicações Java. Note que o compilador Java (javac) encontra-se no JDK.

Para se escrever e executar um programa em Java são necessários um editor para escrevermos
o programa e um prompt de comando, para chamarmos o compilador (javac) e, por fim,
executarmos o programa. No entanto, existe uma forma mais amigável, através das IDEs,
de escrevermos e manipularmos programas em Java, seja para editar, compilar, depurar ou
executar.

10
Introdução à linguagem de programação • CAPÍTULO 1

IDE significa Integrated Development Environment, ou seja, Ambiente Integrado de


Desenvolvimento.

Para a linguagem Java, podem ser destacadas as seguintes IDEs:

» Eclipse;

» NetBeans;

» IntelliJ.

1.3 Tipos de dados

Java é classificada como uma linguagem fortemente tipada. Isso quer dizer que todos os
dados básicos manipulados por um programa Java estão associados a determinado tipo.

Quando realizamos qualquer operação com diversos dados diferentes, o Java usa o
tipo de cada dado para verificar se a operação é válida. Assim, se houver qualquer
incompatibilidade entre os tipos de dados, o compilador Java acusa como um erro.

A linguagem Java tem oito tipos primitivos de dados, como mostrado na Tabela 1.

Tabela 1. Tipos de dados.

Tipo Bits Valor mínimo Valor máximo


boolean 1 true ou false
char 16 até 65.536 caracteres
byte 8 -128 127
short 16 -32.768 32.767
int 32 -2.147.483.648 2.147.483.647
long 64 -9.223.372.036.854.775.808 9.223.372.036.854.775.807
float 32 ~ -1.4e-45 ~ 3.4e38
double 64 ~ -4.9e-324 ~ 1.7e308

Fonte: elaborada pela autora.

Saiba mais

O tamanho dos tipos de dados independe da arquitetura da máquina, ou seja, o tipo int terá sempre 32 bits, seja qual forda
máquina onde o programa Java estiver sendo executado.

1.4 Variáveis e constantes

As variáveis irão armazenar dados que serão, muitas vezes, de um dos tipos de dados
apresentados na seção anterior. E como declaramos uma variável em Java? Vejamos alguns
exemplos:

11
CAPÍTULO 1 • Introdução à linguagem de programação

int _a;

double $c;

char c1, c2, c3;

long nomeBastanteExtensoParaMinhaVariavel;

int i, j;

boolean achou;

Atenção

Quando temos duas ou mais variáveis do mesmo tipo podemos declará-las juntas, separando-as por vírgula.

Pelos exemplos vistos, a declaração de uma variável em Java é:

TipoDeDados IdentificadorDaVariável;

Então, para declarar uma variável para armazenar a idade, por exemplo, teremos:

int idade;

onde int é o tipo de dados

idade é o nome ou identificador da variável

Que nomes podemos usar para variáveis?

Para nomear variáveis, usamos identificadores que seguem as seguintes regras:

» Os identificadores devem começar sempre com uma letra, $ ou

» underscore ( _ ).

» Após o primeiro caractere, são permitidos letras, $, _ , ou dígitos.

» Não há limite de tamanho para o identificador.

» Identificadores em Java são case-sensitive, ou seja, pessoa, PESSOA e Pessoa são


identificadores diferentes.

» Apesar de ser possível, não é recomendável o uso de caracteres de acentuação nos


identificadores (ç, á, é, í, ó, ú, â, ê, ô, à, ã, õ).

» Algumas palavras reservadas não são permitidas como identificadores: abstract,


boolean, break, byte, case, catch, char, class, const, continue, default, do, double, else,

12
Introdução à linguagem de programação • CAPÍTULO 1

extends, final, finally, float, for, goto, if, implements, import, instanceof, int, interface,
long, native, new, package, private, protected, public, return, short, static, strictfp,
super, switch, synchronized, this, throw, throws, transient, try, void, volatile, while,
assert, enum

Importante

» Palavras reservadas não devem ser usadas para identificar variáveis ou constantes ou classes ou métodos.

» Use nomes sugestivos para as variáveis, considerando sempre o contexto do problema.

Podemos inicializar uma variável no momento da declaração. Para isso, é preciso atribuir um
valor à variável. Normalmente, no estudo de algoritmos, o operador de atribuição usado é ←.
Aqui em Java, o operador para atribuição é o = .

Exemplos:

double $c = 0.1;

char c1 = ‘A’, c2, c3;

long nomeBastanteExtensoParaMinhaVariavel = 1000L;

int i = 0, j = 1;

boolean achou = false;

Importante

» O operador = não é usado para testar igualdade em Java.

» Variáveis não inicializadas têm valor indefinido.

» Se você tentar usar uma variável antes de definir seu valor, o compilador Java vai acusar um erro.

E como se define e se inicializa uma constante em Java? A declaração e a inicialização de


constantes têm a mesma sintaxe da declaração e inicialização de variáveis, acrescidas da
palavra final. Exemplos:

final int MAXIMO = 100;

final float PI = 3.14159f;

final char FIM = ‘$’;

final boolean OK = true;

13
CAPÍTULO 1 • Introdução à linguagem de programação

As constantes são, muitas vezes, definidas no programa por trazerem legibilidade e facilitarem
a manutenção. Mais adiante, em outro capítulo, haverá essa percepção.

Importante

Constantes não podem ter seu valor alterado durante o programa. Portanto, caso haja uma tentativa de alterar um desses
valores, o compilador Java acusará erro.

Pelo que foi visto até agora, as variáveis ou constantes podem receber valores inteiros, de
ponto flutuante, caracteres, booleanos e strings, conforme indicado a seguir:

» Valor inteiro

› Composto de dígitos de 0 a 9.

› Pode ser iniciado com sinal negativo (-)

› Exemplos:

19 → int

-3 → int

1265L → long (terminado com L maiúsculo)

-9876L → long (terminado com L maiúsculo)

» Valor ponto flutuante

› Devem conter sempre o ponto (para diferenciar das constantes inteiras)

› Exemplos:

0.234 → double

-125.65 → double

4.93f → float (terminado com f minúsculo)

-12.765f → float (terminado com f minúsculo)

» Valor caracter

› É uma letra ou símbolo entre aspas simples.

› Exemplos:

‘a’ ‘.’ ‘*’

14
Introdução à linguagem de programação • CAPÍTULO 1

» Valor booleano

› São representadas pelas palavras true ou false.

› Note: true significa verdadeiro e false significa falso

» Valor string

› Consiste de uma sequência de zero ou mais caracteres entre aspas duplas.

› Exemplos:

“Oba!”

“Rio de Janeiro”

“A resposta é:”

“a”

“Ela gritou \”Socorro !!!\””

Saiba mais

Quando as aspas fazem parte de uma string, precisamos usar \ antes da aspa. Isso ocorre porque as aspas são usadas para
delimitar uma string, ou seja, para abri-la e fechá-la.

Convenções

Apesar de não ser obrigatório, Java tem algumas convenções de nomenclatura que os
programadores seguem:

» Nomes de variáveis, atributos e métodos: utilizar o formato camelCase: primeira


letra minúscula e primeira letra das demais palavras em maiúscula. Exemplos:

nomeCliente

matriculaAluno

cpf

dataNascimento

» Nomes de constantes: devem ser definidas em caixa alta e usar o underscore como
separador. Exemplos:

LIMITE_SUPERIOR

MAX

15
CAPÍTULO 1 • Introdução à linguagem de programação

» Nomes de classes: utilizar o formato PascalCase, ou seja, todas as primeiras letras


das palavras em maiúsculas. Exemplos:

AloMundo

Cliente

Disciplina

SistemaAcademico

AlunoBolsista

UnidadeEnsino

1.5 Entrada e Saída de Dados

Vejamos como fazer entrada e saída de dados em Java, por enquanto, sem muitos
formalismos.

Revisitando o exemplo do primeiro programa:

public class PrimeiroProg {

public static void main(String [] args)

System.out.println(“Meu primeiro programa.”);

} // fim do método main

} // fim da classe PrimeiroProg

teremos a saída do programa ilustrada na Figura 3.

Figura 3. Saída do programa.

Meu primeiro programa

Fonte: https://pixabay.com/pt/vectors/computador-port%c3%a1til-computador-2298286/ e autora.

16
Introdução à linguagem de programação • CAPÍTULO 1

Observe o uso da classe System e o uso de out, que representa a saída de vídeo (output).
Além deles, usou-se o método println que imprime na tela e faz, em seguida, uma quebra
de linha (ln).

Classe System

» Pertence à biblioteca padrão do Java chamada java.lang.

» A classe System define, dentre outras coisas, os arquivos de entrada e saída padrões.

» O arquivo out representa a saída de vídeo.

» O arquivo in representa a entrada via teclado.

» Note que in e out são objetos e, por isso, podemos acessar seus métodos.

» Para a saída de dados via console (vídeo) usamos os métodos print, println ou printf
do objeto out.

Se a linha de código

System.out.println(“Meu primeiro programa.”);

fosse substituída por

System.out.print(“Meu primeiro programa.”);

a mensagem seria impressa na tela sem quebra de linha, pois o método print imprime na tela,
sem posicionar o cursor na próxima linha.

Para a entrada de dados via teclado, será usada a classe Scanner. Note que Scanner vem de
scan, que remete a “varredura”. Podem ser realizadas várias ações nessa “varredura”, como,
por exemplo: ler o próximo inteiro, ler o próximo valor real (tipos double ou float), entre
outros.

Classe Scanner

» É usada para a entrada de dados.

» Pertence à biblioteca do Java chamada java.util.

» Como a classe Scanner não está definida em uma biblioteca padrão, é necessário
informar onde ela se encontra. Para isso, é preciso usar o comando import: import
java.util.Scanner;

17
CAPÍTULO 1 • Introdução à linguagem de programação

Exemplo: Programa em Java que lê e imprime a idade na tela.

import java.util.Scanner;

public class Leitura {

public static void main(String [] args) {

int idade;

Scanner teclado = new Scanner(System.in);

System.out.println(“Qual a sua idade ? “);

idade = teclado.nextInt();

System.out.println(“Idade = “ + idade);

} // fim do metodo main

} // fim da classe

Figura 4. Saída do programa Leitura.

Qual a sua idade?


25
Idade = 25

Fonte: https://pixabay.com/pt/vectors/computador-port%c3%a1til-computador-2298286/ e autora.

Analisando cada linha do programa Leitura, considerando que foi digitado o valor 25 na
entrada padrão:

» O programa começa a execução pela main, que traduzindo, significa principal.

» A main é sempre escrita dentro de uma classe.

» Tanto a main, quanto a classe são abertas com { e fechadas com }

» A linha import java.util.Scanner; importa a classe Scanner para avisar ao


compilador Java onde ela está definida. Nesse caso, está definida no pacote java.util.

18
Introdução à linguagem de programação • CAPÍTULO 1

» A linha Scanner teclado = new Scanner(System.in); cria um objeto de nome


teclado e diz também que os dados serão “varridos” da entrada padrão (System.
in). Será através do objeto teclado (que poderia ter outro nome seguindo a regra
de identificador) que realizaremos as ações de “obter o próximo inteiro”, “obter o
próximo valor em ponto flutuante” etc.

» A linha System.out.println(“Qual a sua idade? “); imprime na tela do computador a


mensagem: Qual a sua idade?

Após a impressão da mensagem, o cursor é posicionado na linha seguinte, visto que


usou-se println e não print.

» A linha idade = teclado.nextInt(); irá obter o próximo inteiro (nextInt), usando.


para isso, o teclado criado. O valor inteiro lido é atribuído à variável idade, usando o
operador = de atribuição.

» A linha System.out.println(“Idade = “ + idade); imprime Idade = seguido do valor


armazenado na variável idade. Para isso, usou-se o operador + para concatenar
a string Idade = com o valor armazenado na variável idade. O valor da variável é
inteiro, mas para que ocorra a concatenação, ele é convertido para string.

Saiba mais

» Um pacote ou package em Java é um conjunto de classes localizadas na mesma estrutura de diretórios.

» O pacote pode ser padrão, como o java.lang ou não. O pacote java.util tem várias classes, entre elas, a classe Scanner.

» Quando o pacote é padrão não precisamos importá-lo com import.

Existem vários métodos na classe Scanner para fazer a entrada de dados:

» ler um int: nextInt()

» ler um double: nextDouble()

» ler um float: nextFloat()

» ler um caracter: nextLine().charAt(0)

» ler um long: nextLong()

» ler uma string: nextLine()

Exemplo: Programa em Java que lerá duas notas e imprimirá a média.

import java.util.Scanner;

public class Media {

19
CAPÍTULO 1 • Introdução à linguagem de programação

public static void main(String [] args) {

float nota1, nota2, media;

Scanner teclado = new Scanner(System.in);

System.out.print(“Digite a primeira nota: “);

nota1 = teclado.nextFloat();

System.out.print(“Digite a segunda nota:”);

nota2 = teclado.nextFloat();

media = (nota1+nota2)/2;

System.out.println(“Média = “ + media);

} // fim do metodo main

} // fim da classe

Figura 5. Saída do programa Media para as entradas 6,7 e 9,8.

Digite a primeira nota: 6,7


Digite a segunda nota: 9,8
Média = 8.25

Fonte: https://pixabay.com/pt/vectors/computador-port%c3%a1til-computador-2298286/ e autora.

Atenção

O ponto é o separador de casas decimais quando programamos e trabalhamos com float ou double.

Para entrada de dados, o usuário vai usar a vírgula, que é o separador padrão de decimais no sistema numérico brasileiro.

Note que a média foi impressa com duas casas decimais. E se quisermos especificar apenas
uma casa decimal? Nesse caso, é preciso usar o printf ao invés de print ou println. Assim, a
linha

20
Introdução à linguagem de programação • CAPÍTULO 1

System.out.println(“Media = “ + media);

ficará

System.out.printf(“Media = %.1f”, media);

O printf não trabalha com a concatenação (+) e precisa do formato de impressão. O formato
de impressão, que deverá estar sempre entre aspas, será “%.1f” indicando que se trata de
ponto flutuante (%f) e que se terá exatamente uma casa decimal (.1).

Saiba mais

O exemplo em que a idade foi impressa na tela com println:

System.out.println(“Idade = “ + idade);

pode ser reescrito com printf da seguinte forma:

System.out.printf(“Idade = %d\n”, idade);

O formato de impressão é o %d porque idade é uma variável inteira. Note ainda, o uso do código especial \n que indica nova
linha. Com printf é necessário usar \n, sempre entre aspas duplas, se quisermos ter uma nova linha após a impressão.

Existem outras sequências de escape comumente usadas. Veja na tabela 2 a seguir:

Tabela 2. Códigos especiais.

Sequência de escape Descrição


\n Nova linha (new line): posiciona o cursor da tela no início da próxima linha
\t Tabulação (tab): move o cursor de tela para o próximo ponto de tabulação
\” Aspas duplas (“)
\’ Aspas simples (‘)
\\ Contrabarra (\)
\0 Caracter nulo

Fonte: elaborada pela autora.

1.6 Operadores e expressões

Nesta seção serão estudados o operador de atribuição, os operadores aritméticos e


aritméticos de atribuição.

1.6.1 Operador de atribuição

Como visto anteriormente, o sinal = realiza a operação de atribuição, equivalente ao ← usado


em algoritmos para pseudocódigo.

21
CAPÍTULO 1 • Introdução à linguagem de programação

Em Java, o operador de atribuição é responsável por colocar o resultado da expressão à


direita na variável à esquerda:

variável = expressão

A expressão à direita pode ser, por exemplo:

» Uma variável

» Uma constante

» Uma expressão

» Uma chamada de método

Podemos encadear várias atribuições a partir de uma única expressão:

variavel1 = variavel2 = variavel3 = ... = expressão

Exemplos:

int i, j, k;

double max, min;

i = j = k = 1; // Todas as variáveis recebem 1

max = min = 0.0; // As variáveis max e min recebem 0.0

1.6.2 Operadores aritméticos

A tabela 3 destaca os operadores aritméticos da linguagem Java.

Tabela 3. Operados aritméticos.

Operador Ação Tipos


+ Soma Inteiro e ponto flutuante
- Subtração Inteiro e ponto flutuante
* Multiplicação Inteiro e ponto flutuante
/ Divisão Inteiro e ponto flutuante
% Resto da divisão Inteiro
++ Incremento Inteiro e ponto flutuante
-- Decremento Inteiro e ponto flutuante

Fonte: elaborada pela autora.

22
Introdução à linguagem de programação • CAPÍTULO 1

Exemplo: Considere o seguinte trecho de programa em Java:

int x, y, soma, produto, quociente, resto;

double z = 3.0; //atribuindo na declaração

x = 10;

y = 3;

soma = x + y;

produto = x * y;

quociente = x/y;

resto = x%y;

System.out.println(“x = “ + x + “ y = “ + y + “ soma = “ + soma);

System.out.println (“Produto = “ + produto);

System.out.println (“Quociente = “ + quociente);

System.out.println (“Resto = “ + resto);

System.out.println (“Resultado da divisão: “ + x/z);

Para montar o programa completo, executá-lo e obter a saída mostrada na figura 6, só é


necessário pôr as linhas de código acima dentro da main e por fim, a main dentro de uma
classe pública, como mostrado em exemplos anteriores.

Figura 6. Saída do programa.

x = 10 y = 3 soma = 13
Produto = 30
Quociente = 3
Resto = 1
Resultado da divisão:
3.3333333333333335

Fonte: https://pixabay.com/pt/vectors/computador-port%c3%a1til-computador-2298286/ e autora.

Temos no trecho desse programa várias expressões, a saber: x * y, x/y, x/z e x%y. Observe
que, como não foi usado printf, apareceram muitas casas decimais. Se a linha

System.out.println (“Resultado da divisão: “ + x/z);

23
CAPÍTULO 1 • Introdução à linguagem de programação

for substituída por

System.out.printf (“Resultado da divisão: %.2f” , x/z);

a tela de saída ficará conforme ilustrado na Figura 7.

Figura 7. Saída do programa usando printf.

x = 10 y = 3 soma = 13
Produto = 30
Quociente = 3
Resto = 1
Resultado da divisão:
3.3333333333333335

Fonte: https://pixabay.com/pt/vectors/computador-port%c3%a1til-computador-2298286/ e autora.

Quando existem vários operadores em uma mesma expressão, é importante saber a ordem
de precedência, ou seja, que operação deve ser realizada primeiro e quais as próximas
operações a serem realizadas.

Tabela 4. Precedência e associação dos operadores.

Operadores Associação
++ -- Direita para esquerda
* / % Esquerda para direita
+ - Esquerda para direita

Fonte: elaborada pela autora.

Por exemplo, a multiplicação, a divisão e o cálculo do resto são feitos antes da soma e
subtração. E quando se faz a multiplicação, se lê a expressão da esquerda para a direita. E
quando se tem multiplicação e divisão em uma mesma expressão? Vale a regra matemática: a
operação que aparecer primeiro é feita primeiro.

Mas, note que, assim como na Matemática, é possível mudar a precedência das operações
usando parênteses nas expressões. Vejamos alguns exemplos:

float a, b, i = 10, j = 30, k = 40;

int z = 10;

a = i + j / k; // a = 10.75. Primeiro dividiu para depois somar.

b = (i + j) / k; // b = 1. Primeiro somou e depois dividiu.

z++; //z passará a valer 11. O efeito com ++z; seria o mesmo.

24
Introdução à linguagem de programação • CAPÍTULO 1

Importante

» O operador / pode ser aplicado tanto a valores inteiros quanto a valores de ponto flutuante (float ou double).

» Quando todos os argumentos do operador / são inteiros, então o resultado será um número inteiro, ou seja, a parte
decimal é desprezada.

int i = 6, j = 3, k = 4, r;

r = i / j; r recebe o valor 2

r = i / k; r recebe o valor 1 e não 1.5

Vejamos agora os operadores de incremento e decremento, que são muito usados em Java.

Os operadores ++ e -- podem ser pré-fixados ou pós-fixados. Assim:

{ x++

++x
usa o valor de x e depois incrementa x

incrementa x e depois usa o valor já incrementado

Analogamente, temos a mesma ideia para o operador de decremento, considerando


naturalmente, a diminuição de uma unidade.

Exemplo: Qual o valor final de i, j e k nas expressões abaixo?

int i, j, k;

i = 10;

j = i++;

k = ++j;

O trecho acima pode ser reescrito como:

i = 10;

j = i;

i++;

++j;

k = j;

Assim, i, j e k terão valor 11.

25
CAPÍTULO 1 • Introdução à linguagem de programação

Observe o seguinte:

» j = i++; usa incremento pós-fixado. Então, primeiro se atribui ( j = i; ) para depois


incrementar ( i++; )

» k = ++j; usa incremento pré-fixado. Então, primeiro se incrementa ( ++j; ) para


depois atribuir a variável k o valor resultante do incremento.

1.6.3 Operadores aritméticos de atribuição

Em programação é comum termos, por exemplo:

quantidade = quantidade + 10;

variável variável expressão

salario = salario - salario * percentual / 100;

variável variável expressão

Em Java, é muito comum combinar os operadores aritméticos com o operador de


atribuição. Veja a tabela a seguir:

Tabela 5. Operadores aritméticos de atribuição.

Expressão normal Expressão


var = var + expressão var += expressão
var = var - expressão var -= expressão
var = var * expressão var *= expressão
var = var / expressão var /= expressão
var = var % expressão var %= expressão

Fonte: elaborada pela autora.

Então, como ficarão os exemplos mostrados? Considere que as variáveis quantidade, salario e
percentual já foram previamente declaradas.

Quantidade = quantidade + 10; ficará quantidade += 10;

salario = salario – salario * percentual / 100;

ficará

salario -= salario * percentual / 100;

26
Introdução à linguagem de programação • CAPÍTULO 1

Saiba mais

Sintaxe de uma linguagem de programação diz respeito às regras ou normas da linguagem. Por exemplo, toda declaração
de variável em Java é finalizada com ponto e vírgula. Isso é uma regra da linguagem, que pode ou não existir em outras
linguagens de programação.

Mais adiante veremos, dentro de outro contexto, os operadores relacionais e os lógicos.

1.7 Conversão de Tipos

Quando misturamos vários tipos em uma expressão, o Java tenta sempre converter os tipos
com valores menos significativos para tipos mais significativos para não haver perda de
dados durante o processamento.

Essa conversão se dá na seguinte ordem:

byte → short → int → long → float → double

Exemplos:

Se uma expressão envolve tipos byte e int, os valores das variáveis do tipo byte serão
convertidos para int antes de avaliar a expressão.

Se uma expressão envolve os tipos int, float e double, os valores das variáveis int e float serão
convertidos para double antes da avaliação.

Uma expressão só pode ser atribuída a uma variável se o tipo dessa expressão for igual
ou menos significativo que o tipo da variável. Caso contrário, será gerado um erro de
compilação. Assim, a atribuição deve ser feita obedecendo à seguinte ordem:

byte → short → int → long → float → double

Exemplos:

» Um expressão do tipo float pode ser armazenada em uma variável do tipo float ou
double.

» Uma expressão do tipo long pode ser armazenada em uma variável do tipo long,
float ou double. Se tentar atribuir a uma variável do tipo int, ocorrerá erro.

27
CAPÍTULO 1 • Introdução à linguagem de programação

1.7.1 Operador de casting

Para forçarmos a conversão de um tipo para outro usamos o operador de casting. Existem
duas sintaxes:

(tipo) variável converte a variável para o tipo entre parênteses

(tipo) (expressão) converte o resultado da expressão para o tipo indicado.

Exemplos:

int i = 6, j = 3, k = 4;

(float) i / j converte i para 6.0 e o resultado é 2.0

(float)(i) / k converte i para 6.0 e o resultado é 1.5

(float)(i / k) converte 1 para 1.0, ou seja, só aplica o casting depois da divisão

Para facilitar o seu aprendizado...

O que é preciso instalar para começar a testar e a fazer os primeiros programas?

O JavaSE e alguma IDE de sua preferência, dentre as sugeridas.

» Para fazer o download do Java SE Development Kit, acesse a página: https://www.


oracle.com/java/ e siga os passos, seja para Linux, Windows ou macOS.

» Para instalar o Eclipse, por exemplo, acesse a página: www.eclipse.org e siga os


passos para o download.

» Uma vez que tudo foi devidamente instalado, como começar a usar o Eclipse?
Vamos focar no que é essencial, visto que o Eclipse tem muitas opções além do
que iremos usar aqui.

» Note que a disciplina é de programação. Então, o foco não é ensinar todos os


recursos de todas as IDEs. Quando se usa uma IDE, fica simples usar outras. Além
disso, à medida que se usa uma IDE, mais recursos são descobertos.

» Veja que o menu Help tem uma ajuda, inclusive com tutorial.

Passos para criar um programa Java (arquivo de extensão .java), compilar e executar na IDE
eclipse (Version: 2022-03 (4.23.0)):

Passo 1: Após abrir a IDE, clique em File – New – Java Project

28
Introdução à linguagem de programação • CAPÍTULO 1

Figura 8. Criando o projeto Java.

Fonte: elaborada pela autora.

Passo 2: Dê o nome do projeto (Project name). No caso, PrimeiroProg. Em seguida, no final


da mesma janela, desmarque Create module-info.java file e logo depois, clique no botão
Finish. Note que Finish significa terminar/finalizar.

Figura 9. Criando o projeto Java.

Fonte: elaborada pela autora.

Passo 3: O efeito do passo anterior é a seguinte janela

Figura 10. O primeiro projeto.

Fonte: elaborada pela autora.

29
CAPÍTULO 1 • Introdução à linguagem de programação

Passo 4: Com o botão direito do mouse na pasta src, escolha New – File, para criar um novo
arquivo na pasta. Note que src vem de source, que significa fonte. Assim, na pasta src será
escrito o arquivo .java, que é o arquivo fonte.

Figura 11. Para criar um arquivo na pasta src.

Fonte: elaborada pela autora.

Passo 5: Aparecerá uma nova janela, na qual deverá ser digitado o nome do arquivo fonte,
que será PrimeiroProg. Logo em seguida, clique no botão Finish para finalizar a criação do
arquivo.

Figura 12. Criando arquivo em src com extensão .java.

Fonte: elaborada pela autora.

Passo 6: Foi criado um arquivo (ainda vazio) de nome PrimeiroProg dentro do pacote default
(padrão). Veja à direita, parte do arquivo .java onde serão escritas as linhas do programa.

30
Introdução à linguagem de programação • CAPÍTULO 1

Figura 13. Criado o arquivo no pacote default.

Fonte: elaborada pela autora.

Passo 7: Editando o primeiro programa na janela do editor à direita, conforme a Figura 13.

public class PrimeiroProg {

public static void main (String args[]) {

System.out.println(“Primeiro programa em Java.”);

Passo 8: Salvando, compilando e executando com Run. Note que apenas para salvar,
pode ser usado o ícone do disquete ou escolher File – Save. Para apenas compilar, escolha
Project – Build Project. Mas se você já está decidido que quer executar, escolha Run – Run,
pois o projeto será compilado e executado.

Note que para as opções do menu existem teclas de atalho.

Figura 14. Executando.

Fonte: elaborada pela autora.

31
CAPÍTULO 1 • Introdução à linguagem de programação

Observe a janela do Console, onde aparece o resultado da execução do programa.

Passo 9: Provocando um erro de sintaxe no arquivo. Veja que o erro já é apontado de imediato.
Apareceu a mensagem indicando “erro de sintaxe, insira ; para completar o bloco”. Nem foi
preciso compilar, neste caso.

Figura 15. Erro de compilação.

Fonte: elaborada pela autora.

Sintetizando

Síntese do capítulo:

» Java é uma linguagem cuja grande característica é a portabilidade.

» A plataforma Java é definida apenas em software e tem dois componentes: a JVM e a API Java.

» JDK é o kit de desenvolvimento Java que inclui o compilador javac, o ambiente de execução (JRE), debugging, entre outros.

» As IDEs facilitam a criação, compilação, depuração e execução de programas em Java.

» Existem oito tipos de dados primitivos em Java: int, long, float, double, char, boolean, byte e short.

» Para definir uma constante usa-se a palavra reservada final.

» Toda declaração de variável em Java começa pelo tipo e é finalizada com ponto e vírgula.

» Para saída de dados usamos System.out.print ou System.out.println ou System.out.printf.

» Para entrada de dados podemos usar a classe Scanner, que precisa ser importada com import.

» A classe Scanner encontra-se no pacote java.util.

» Operador de atribuição: =

» Operadores aritméticos: +, - , *, /, %, ++ e - - (decremento)

» Operadores aritméticos de atribuição: +=, -=, *=, /= e %=

» Operador casting: (tipo) variável ou (tipo)(expressão)

32
COMANDOS DA LINGUAGEM JAVA
CAPÍTULO
2
Introdução ao capítulo

Neste capítulo serão estudados vários comandos da linguagem Java, a saber: comandos de
seleção (if, if/else e switch...case) e comandos de repetição (while, for e do/while). Além
disso, serão estudados os operadores relacionais e lógicos, entre outros, nos levando ao uso da
tabela verdade de cada operador lógico.

Objetivos do capítulo

» Apresentar os comandos da linguagem de programação Java.

» Escrever programas mais elaborados usando mais recursos da linguagem de


programação Java.

2.1 Comandos de seleção

Assim como acontece no dia a dia, os programas em Java também usam condições para
decidir se determinadas instruções serão executadas ou não.

Figura 16. Decisão.

Fonte: https://www.shutterstock.com/pt/image-vector/business-man-character-has-take-difficult-357576257.

33
CAPÍTULO 2 • Comandos da linguagem Java

As estruturas de seleção são usadas para decidir se um conjunto de instruções deve ou


não ser executado. Essa decisão está baseada em uma ou mais condições. Dessa forma,
podemos ter mais de um comando, conforme ilustrado pela figura 17.

Figura 17. Estruturas de seleção.

Seleção
Simples

Estruturas
de Seleção
Seleção de
Seleção
Múltipla
Escolha
Composta

Fonte: elaborada pela autora.

2.1.1 Comando condicional simples

A seleção simples é implementada pelo comando if. Note que if significa se.

Sintaxe:

if (expressão_lógica) comando;

if (expressão_lógica) {

bloco de instruções

Importante

» Um bloco de instruções é um conjunto de duas ou mais instruções.

» A expressão_lógica é uma expressão que pode ser verdadeira ou falsa.

Se for verdadeira, o comando ou o bloco de instruções será executado. Caso contrário, ou seja, se a expressão_lógica for
falsa, nem o comando e nem o bloco de instruções será executado.

» As expressões lógicas, ou seja, as expressões que podem ser verdadeiras ou falsas, podem fazer uso de operadores
relacionais e/ou lógicos.

34
Comandos da linguagem Java • CAPÍTULO 2

Vejamos exemplos com trechos de programa em Java.

int idade = 20;

if (idade >= 18)

System.out.println(“Maior de idade.”);

System.out.println(“Continuando... “);

Análise do exemplo: Primeiro a variável idade recebe o valor 20. Em seguida, é feito um teste:
idade é maior ou igual a 18? Verdadeiro ou falso? Note o uso do operador relacional >= (maior
ou igual).

Vejamos:

» Se o teste lógico for verdadeiro, a instrução System.out.println(“Maior de idade.”);


será executada e segue-se para a próxima instrução após o if. Então, nesse caso, será
impresso na tela:

Maior de idade

Continuando...

» Se o teste lógico for falso, a instrução System.out.println(“Maior de idade.”); não será


executada e segue-se para a próxima instrução após o if, Nesse caso, será impressa na
tela apenas a mensagem Continuando...

Vejamos outro exemplo, usando um bloco de instruções.

int idade = 20;

if (idade >= 18)

System.out.println(“Maior de idade.”);

System.out.println(“Você pode tirar carteira de motorista.”);

A única diferença deste último exemplo para o anterior é que as duas instruções, a saber:

System.out.println(“Maior de idade.”);

System.out.println(“Você pode tirar carteira de motorista.”);

35
CAPÍTULO 2 • Comandos da linguagem Java

serão executadas caso a condição (idade >= 18) seja verdadeira e depois o fluxo da execução
seguirá para a próxima instrução após o bloco. Caso a condição seja falsa, nada no bloco
será executado e o fluxo da execução seguirá para a primeira instrução após o fim do bloco.

Atenção

Note que todo bloco, visto aqui ou com qualquer outro comando, terá duas ou mais instruções que deverão ser postas,
obrigatoriamente, entre chaves.

Qualquer comando, além do comando condicional simples, que trabalhe com expressões lógicas poderá ou não fazer uso de
operadores relacionais e lógicos.

Nos dois últimos exemplos foi usado o operador relacional >= (maior igual). Para podermos
comparar valores ou expressões ou conteúdo de variáveis, por exemplo, a linguagem Java
oferece os operadores relacionais. Além estes, existem os operadores lógicos que nos
permitem escrever expressões lógicas mais interessantes.

» Operadores relacionais

Tabela 6. Operadores relacionais.

Operador Significado
> Maior que
< Menor que
>= Maior ou igual a
<= Menor ou igual a
== Igual a
!= Diferente de

Fonte: elaborada pela autora.

» A sintaxe das operações relacionais é a seguinte:

expressão_arimética_1 op_relacional expressão_aritmética_2

onde op_relacional é um dos operadores da tabela anterior.

» Os operadores aritméticos têm precedência sobre os operadores relacionais.


Assim, se colocarmos esses dois tipos de operadores em uma mesma expressão, os
operadores aritméticos serão avaliados primeiro e, em seguida, os relacionais.

Exemplos:

1 + 3 >= 3 + 6 equivale a (1 + 3) >= (3 + 6), que equivale a 4 >= 9

5.0 / 3 <= 10 / (4 + 1) equivale a (5.0 / 3) <= (10 / (4 + 1))

36
Comandos da linguagem Java • CAPÍTULO 2

» Operadores lógicos

Tabela 7. Operadores lógicos.

Operador Significado
&& E (AND)
|| OU (OR)
! NEGAÇÃO (NOT)

Fonte: elaborada pela autora.

» A sintaxe das operações lógicas é:

expressão_relacional_1 op_lógico expressão_relacional_2

Exemplos de trecho de programa em Java com operadores relacionais e lógicos:

int numero1 = 10, numero2 = 20;

if (numero1 < numero2)

System.out.println(“O primeiro número é menor que o segundo. “);

int numero1 = 10, numero2 = 20;

if (numero1 < numero2 && numero2 < 100 )

System.out.println(“O primeiro número é menor que o segundo e o segundo número é


menor que 100 “);

Note que a condição numero1 < numero2 é verdadeira, em ambos os trechos. Considerando
o 2º exemplo, temos que a condição numero2 < 100 também é verdadeira. Nesse caso, temos
que a condição é inteiramente verdadeira e, assim, a instrução

System.out.println(“O primeiro número é menor que o segundo e o segundo número é


menor que 100 “);

será executada.

Para podermos trabalhar com expressões que usam operadores lógicos, é preciso que se tenha
conhecimento da tabela verdade desses operadores. Vamos, então, relembrar!

» Tabela Verdade

Considere que Expr1 e Expr2 são duas expressões que podem ser verdadeiras ou falsas,
sendo V para verdadeiro e F para falso.

37
CAPÍTULO 2 • Comandos da linguagem Java

Tabela 8. Tabela verdade do e lógico.

&& que é o E lógico


Expr1 Expr2 Expr1 && Expr2
V V V
V F F
F V F
F F F

Fonte: elaborada pela autora.

Tabela 9. Tabela verdade do ou lógico.

|| que é o OU lógico
Expr1 Expr2 Expr1 || Expr2
V V V
V F V
F V V
F F F

Fonte: elaborada pela autora.

Tabela 10. Tabela verdade do não lógico.

! que é o NÃO
Expr ! Expr
V F
F V

Fonte: elaborada pela autora.

Exemplos para analisar se a expressão é verdadeira ou falsa:

float x = 3.0f, y = 1.5f;

int a = 2, b = 4, c = 3;

x > 0 || y > 0 é verdadeira

a + b > c && x – y >= 0 é verdadeira

a > b || b > c && a <= c || c == b é verdadeira

b * b - 4 * a * c >= 0 && 2 * a > 0 é falsa

(a + x > 0 && 2 * y – a > 0) || b * c > x * y é verdadeira

Qual foi o raciocínio? Vejamos, considerando aqui, para facilitar, V para verdadeiro e F para
falso:

38
Comandos da linguagem Java • CAPÍTULO 2

» x > 0 || y > 0 V ou V → verdadeira

» a + b > c && x – y >= 0 6 > 3 e 1.5 >= 0

VeV → verdadeira

» a > b || b > c && a <= c || c == b F ou V e V ou F

→V eV → verdadeira

» b * b - 4 * a * c >= 0 && 2 * a > 0

Então: 16 – 24 >= 0 e 4 > 0

→ -8 >= 0 e 4 > 0

→ F eV

→ falsa

» (a + x > 0 && 2 * y – a > 0) || b * c > x * y

Então: 5.0 > 0 e 3.0-2 >0) ou 12 > 4.5

→ (V e V) ou V

→ V ou V → verdadeira

Até agora vimos muitos tipos de operadores: aritméticos, de atribuição, de casting, relacionais,
lógicos etc. Como fica a precedência quando temos vários operadores em uma grande
expressão? Para responder a essa pergunta, temos que ver a tabela 11, que também mostra
como associar esses operadores: da direita para a esquerda (←) ou da esquerda para a direita
(→).

Tabela 11. Precedência e associatividade dos operadores.

Operador Descrição Associatividade


1º - Menos unário ←
(tipo Conversão de tipo
! NÃO lógico
2º * Multiplicação →
/ Divisão
% Resto
3º + Soma →
- Subtração
4º > Maior →
< Menor
>= Maior ou igual
<= Menor ou igual

39
CAPÍTULO 2 • Comandos da linguagem Java

Operador Descrição Associatividade


5º == Igual →
!= Diferente
6º && E lógico →
7º || OU lógico →
8º = Atribuição ←

Fonte: elaborada pela autora.

2.1.2 Comando condicional composto

Considere que seja preciso calcular a média de duas notas e a partir daí, dar uma das
mensagens: “Aprovado” ou “Reprovado”. Vamos considerar que a média para aprovação seja
7.0.

Para este problema, precisamos usar o comando condicional composto. Em Java, é o


comando if ...else. Note que if significa se e else significa senão.

Sintaxe:

if (expressão_lógica)

comando1;

else

comando2;

if (expressão_lógica)

bloco1 de instruções

else

bloco2 de instruções

if (expressão_lógica1)

comando1;

else if (expressão_lógica 2)

comando2;

else

comando3;
40
Comandos da linguagem Java • CAPÍTULO 2

Importante

» Um bloco de comandos/instruções é formado por duas ou mais instruções e deve estar entre chaves.

» Em um bloco de comandos, seja no if ou no else, é possível termos outro comando condicional, simples ou composto,
bem como qualquer outra instrução, como uma atribuição, por exemplo.

» O último retângulo mostra o comando if/else aninhado ou encadeado. Nesse caso, no lugar de qualquer um dos
comandos (comando1 ou comando2 ou comando3) é possível também termos blocos de instruções.

Exemplo: Para fazer um programa para o problema proposto, será adicionado o trecho com if/
else a um exemplo já visto.

import java.util.Scanner;

public class Media {

public static void main(String [] args) {

float nota1, nota2, media;

Scanner teclado = new Scanner(System.in);

System.out.println(“Digite a primeira nota: “);

nota1 = teclado.nextFloat();

System.out.println(“Digite a segunda nota: “);

nota2 = teclado.nextFloat();

media = (nota1+nota2)/2;

System.out.println(“Media = “ + media);

if (media >= 7.0)

System.out.println(“Aprovado “);

else

41
CAPÍTULO 2 • Comandos da linguagem Java

System.out.println(“Reprovado “);

} //fim main

} //fim classe

O comando condicional composto pode ser substituído por uma versão mais enxuta se for
usado o operador ternário ? : . Portanto, tal operador é usado em expressões condicionais e
sua sintaxe é:

condição ? expressão_1 : expressão_2

A avaliação dessa expressão é feita da seguinte forma:

se condição for verdadeira então

o resultado da expressão é expressão_1

senão

o resultado da expressão é expressão_2

Exemplo: Seja um trecho de programa em Java.

int menor, i, j;

if (i < j)
menor = i;
else menor = i < j ? i : j;
menor = j;

Exemplo: Como reescrever trecho com if/else de um programa anterior?

Vejamos a versão com if/else e a versão com o operador ? :

» Com if/else

if (media >= 7.0)

System.out.println(“Aprovado “);

else

System.out.println(“Reprovado “);

42
Comandos da linguagem Java • CAPÍTULO 2

» Com o operador ? :

System.out.println(media >= 7.0 ? “Aprovado “ : “Reprovado “);

Exemplo: Qual é o valor de i em cada expressão?

int i = 1, j = 2, k = 3;

i = i > k ? i : k; // Resposta: 3

i = i > 0 ? j : k; //Resposta : 2

i = j > i ? ++k : --k; // Resposta: 4

Exemplo: Considere um trecho de programa em Java com o comando if...else encadeado


ou aninhado.

int num;

Scanner teclado = new Scanner(System.in);

System.out.println(“Digite um número:”);

num = teclado.nextInt();

if (num < 0)

System.out.println(“Valor negativo. “);

else

if (num == 0)

System.out.println(“Valor nulo. “);

else

System.out.println(“Valor positivo. “);

2.1.3 Comando switch

Considere um trecho de código em Java com vários testes em igualdade. Pode ser ruim ler
ou dar manutenção a um programa deste tipo? Sim! Imagine se o programa tiver muito mais
linhas de código.

43
CAPÍTULO 2 • Comandos da linguagem Java

// Trecho de um programa em Java

int num;

Scanner teclado = new Scanner(System.in);

System.out.println(“Digite um numero: “);

num = teclado.nextInt();

if (num == 10)

System.out.println(“Valor 10.”);

else

if (num == 20)

System.out.println(“Valor 20.”);

else

if (num == 30)

System.out.println(“Valor 30.”);

else

if (num == 40)

System.out.println(“Valor 40.”);

else

System.out.println(“Nenhum valor dentre o esperado.”);

Figura 18. Então, qual é a solução?

Usar o comando
switch.

Fonte: https://pixabay.com/pt/vectors/l%c3%a2mpada-el%c3%a9trica-id%c3%a9ia-ilumina%c3%a7%c3%a3o-1926533/.

44
Comandos da linguagem Java • CAPÍTULO 2

Veja o trecho anterior reescrito com switch:

int num;

Scanner teclado = new Scanner(System.in);

System.out.println(“Digite um número: “);

num = teclado.nextInt();

switch (num) {

case 10: System.out.println(“Valor 10. “);

break;

case 20: System.out.println(“Valor 20. “);

break;

case 30: System.out.println(“Valor 30. “);

break;

case 40: System.out.println(“Valor 40. “);

break;

default: System.out.println(“Nenhum valor dentre o esperado. “);

break; //este break é opcional, pois está no default

} //fim do switch

Observe o seguinte:

» O valor de num pode ou não estar de acordo com um dos valores constantes (10
ou 20 ou 30 ou 40). Caso não esteja, a opção default (padrão) será executada.

» Quando o comando break é executado, o switch termina.

» O default é opcional, mas quando é escrito no código, é o último trecho dentro do


switch.

45
CAPÍTULO 2 • Comandos da linguagem Java

» Quando nenhum case é alcançado, o default é executado e o switch termina. Daí a


razão do break ser opcional no default.

Importante

O comando switch:

» É um comando de seleção semelhante ao if-else, porém ele é mais recomendado quando temos muitos caminhos
possíveis a partir de uma única condição.

» A expressão do switch deve ser do tipo caractere (char) ou inteiro (byte, short, int ou long) ou String.

» O comando break é usado para terminar o switch.

Sintaxe:

switch(expressão) {

case valor1: comando1; //pode ter 1 ou mais comandos

comando2;

break;

case valor2: comando3; //pode ter 1 ou mais comandos

break;

case valor3: comando4; //pode ter 1 ou mais comandos

comando5;

break;

default: comando6; //pode ter 1 ou mais comandos

break; //opcional no default

Atenção

» valor1, valor2, valor3, etc., podem ser variáveis ou constantes.

» Quando o switch encontra uma opção igual ao valor da expressão, ele executa todos os comandos daí em diante até
encontrar o comando break.

» É possível não se ter comandos em cases.

46
Comandos da linguagem Java • CAPÍTULO 2

Exemplo: Trecho de programa em Java com o comando switch. Considere a variável caracter
previamente declarada char caracter; e definida.

switch (caracter) {

case ‘a’:

case ‘e’:

case ‘i’:

case ‘o’:

case ‘u’: System.out.println(“É uma vogal”);

break;

case ‘x’: System.out.println(“Letra X”);

default: System.out.println(“Letra inválida”);

break;

Vamos simular algumas execuções!

1ª execução: Suponha que o caracter seja o e. Neste caso, o case e é alcançado e como está
vazio, segue-se em frente, “invadindo” os cases seguintes, até encontrar um break e o switch
terminar.

Então, será impressa a mensagem É uma vogal e depois, o switch termina. Note que o mesmo
ocorrerá para qualquer vogal.

2ª execução: Suponha que o caracter seja o x. Neste caso, o case x é alcançado e é impresso
Letra X . Como não tem break neste case, a execução continua e invade o trecho a seguir, que
é o default. Então, logo em seguida é impressa Letra inválida e, por fim, o switch termina.

3ª execução: Suponha que caracter armazene um valor que não tenha em nenhum case.
Neste caso, a opção default será executada, imprimindo a mensagem Letra inválida, para
logo em seguida o switch terminar.

47
CAPÍTULO 2 • Comandos da linguagem Java

2.2 Comandos de repetição

Há três comandos de repetição:

» while

» for

» do...while

2.2.1 Comando while

Avalia uma expressão lógica e executa um bloco de comando enquanto a expressão lógica
for verdadeira, sendo que o bloco é executado ZERO ou mais vezes. Note que while significa
enquanto.

Sintaxe:

while (expressão_lógica)

bloco de comandos;

while (expressão_lógica)

comando;

Exemplo: Considere o trecho de programa em Java que imprime os números de 1 até 3.

int num;

num = 1;

while (num <= 3) //enquanto num for menor ou igual a 3

System.out.println(num); //imprime na tela o valor de num

num++; //pega o próximo número

Observe o passo a passo no quadro a seguir:

48
Comandos da linguagem Java • CAPÍTULO 2

Quadro 1. Teste de mesa.

num num <= 3 O que é impresso na tela?


1 1<= 3 ? Verdadeiro 1
2 2 <= 3 ? Verdadeiro 2
3 3 <= 3 ? Verdadeiro 3
4 <= 3 ? Falso

Fonte: elaborado pela autora.

2.2.2 Comando for

Este comando executa um bloco de comando enquanto uma expressão lógica for verdadeira.

Sintaxe:

for (inicialização; expressão_lógica; incremento e/ou decremento)

comando;

for (inicialização; expressão_lógica; incremento e/ou decremento)

bloco de comandos;

A execução do for se dá da seguinte forma:

1. Executa a expressão de inicialização.

2. Testa a expressão lógica. Se for FALSA termina o for.

3. Executa o bloco de comandos.

4. Executa a expressão de incremento e/ou decremento.

5. Volta para o passo 2.

O comando for é equivalente ao comando while. De forma geral, podemos ter:

for (inicialização; expressão_lógica; incremento/decremento) {

comando1;

comando2;

49
CAPÍTULO 2 • Comandos da linguagem Java

Reescrevendo com o comando while:

inicialização;

while (expressão_lógica) {

comando1;

comando2;

incremento/decremento;

Saiba mais

O for é constituído de três partes: inicialização, expressão lógica e incremento/decremento. Entretanto, nenhuma dessas
partes é obrigatória.

Exemplo: Considere o trecho de programa em Java que imprime os números de 1 até 3.


Equivale ao trecho escrito anteriormente com while.

int num;

for (num = 1; num <= 3; num++)

System.out.println(num); //imprime na tela o valor de num

Observe que:

» num = 1 é a inicialização da variável num

» num <= 3 é a expressão ou teste lógico

» num++ é o incremento da variável num

» System.out.println(num); é a instrução/comando

Exemplo: O exemplo anterior pode ser reescrito das seguintes formas:

int num;

for (num = 1; num <= 3; ) {

System.out.println(num); //imprime na tela o valor de num

num++; //incrementa num

50
Comandos da linguagem Java • CAPÍTULO 2

Ou ainda:

int num = 1;

for ( ; num <= 3; ) {

System.out.println(num);

num++;

2.2.3 Comando do...while

No caso deste comando é necessário primeiro fazer (do) para depois testar. Então, podemos
ler: faça o bloco de comandos enquanto for verdade a condição ou expressão lógica. Dessa
forma, o bloco é executado uma ou mais vezes.

Sintaxe:

do {

// uma ou mais linhas de código

} while (expressão_logica);

É interessante usar este comando quando, por exemplo, o usuário entra com um valor
inválido e queremos dar outra(s) chance(s) para que a entrada seja corretamente fornecida.

Exemplo: Seja um programa em Java para ler um valor inteiro maior que zero e depois
imprimir os números de 1 até o valor fornecido na entrada.

Para este programa serão usados dois comandos de repetição diferentes:

1. Para tratar a entrada do valor inteiro que deve ser maior que zero será usado o
comando do...while.

2. Para imprimir os números de 1 até o valor inteiro positivo é possível usar for ou
while. Vejamos com for.

import java.util.Scanner;

public class Lista {

public static void main(String args[]) {

51
CAPÍTULO 2 • Comandos da linguagem Java

int n, i;

Scanner teclado = new Scanner(System.in);

do {

System.out.print(“Digite um valor > 0: “);

n = teclado.nextInt();

if (n <= 0)

System.out.println(“Entrada invalida. “);

} while (n <= 0);

System.out.println(“Imprime valores de 1 a “ + n);

for (i = 1; i <= n; i++)

System.out.println(i);

} //fim da main

} //fim da classe Lista

Figura 19. Saída do programa anterior.

Fonte: elaborada pela autora.

52
Comandos da linguagem Java • CAPÍTULO 2

Alguns comentários sobre o programa anterior:

1. A execução do trecho

do {

System.out.print(“Digite um valor > 0: “);

n = teclado.nextInt();

if (n <= 0)

System.out.println(“Entrada invalida. “);

} while (n <= 0);

é repetida enquanto o valor de n for menor ou igual a 0. Quando for digitado um


valor > 0, ou seja, positivo, o teste lógico do comando do...while será falso e a
repetição terminará.

2. Considere que o 1º valor digitado para n foi -1. Então n recebeu -1. Em seguida, o
teste do if é executado. Ou seja, -1 <= 0 ? Sim! Verdadeiro. Então, a instrução dentro
do if é executada e é impressa na tela a mensagem Entrada inválida. Em seguida, a
condição do do...while é testada e também é verdadeira. Isso faz com que o fluxo da
execução volte para o do (faça) e entre no bloco do comando.

3. Considere que o 2º valor digitado para n foi 3. Então n recebeu 3. Em seguida, o


teste do if é executado. Ou seja, 3 > 0 ? Não! Falso. Assim, a instrução dentro do if
não é executada e segue-se para o teste do do...while, que também é falso. Nesse
momento, a repetição com do..while termina e o fluxo da execução segue para o
trecho:

System.out.println(“Imprime valores de 1 a “ + n);

for (i = 1; i <= n; i++)

System.out.println(i);

que primeiramente, imprime na tela a mensagem Imprime valores de 1 a 3 e


depois faz a repetição com for, que será explicada no passo a seguir.

4. Para entender o trecho do for, veja o quadro a seguir:

53
CAPÍTULO 2 • Comandos da linguagem Java

Quadro 2. Teste de mesa.

i n i <= n TELA
1 3 1 <= 3? Verdadeiro 1
2 2 <= 3? Verdadeiro 2
3 3 <= 3? Verdadeiro 3
4 4 <= 3? Falso. Sai do for

Fonte: elaborado pela autora.

5. O trecho

for (i = 1; i <= n; i++)

System.out.println(i);

poderia ter sido reescrito com while da seguinte forma:

I = 1;

while (i <= n) {

System.out.println(i);

i++;

Além dos comandos de seleção e repetição, veremos os comandos break e continue.

Conforme já estudado, o comando break pode ser usado nos cases do comando switch para
permitir a saída do switch. Mas existe outro uso: a saída de loops, ou seja, dos blocos de
repetição escritos com for, while ou do...while.

O trecho com do...while, do exemplo anterior, pode usar o comando break da seguinte forma:

do {

System.out.print““Digite um valor > 0:““);

n = teclado.nextInt();

if (n <= 0)

System.out.println““Entrada invalida.““);

else

break; //sai da repetição com do...while

} while (n <= 0);

54
Comandos da linguagem Java • CAPÍTULO 2

Assim, se o valor de n for maior que zero, por exemplo 5, o teste do if será falso e o trecho
do else será executado. Ou seja, o break será executado, interrompendo o loop. Nesse caso, a
expressão lógica do do...while não será alcançada.

Se por um lado o comando break termina o loop, o comando continue força o início da
próxima iteração do loop de um comando de repetição. Vejamos um exemplo.

Exemplo:

for (i = 5; i >= 1; i--) {

if (i == 3)

continue; //volta para a linha do for

System.out.println(i);

Vamos fazer um teste de mesa no quadro 3:

Quadro 3. Teste de mesa.

i i >= 1 i == 3 TELA
5 5 >= 1? Verdadeiro Falso
4 4 >= 1? Verdadeiro Falso 5
3 3 >= 1? Verdadeiro Verdadeiro 4
Obs.: Executa o continue, que direciona a execução 2
para a linha do for, não imprimindo o valor 3.
1
2 2 >= 1? Verdadeiro Falso
1 1 >= 1? Verdadeiro Falso
0 0 >= 1? Falso (sai do for)

Fonte: elaborado pela autora.

Para facilitar o seu aprendizado...

Vejamos alguns exemplos de programa em Java usando Eclipse, seguindo um outro possível
caminho diferente do mostrado no Capítulo 1.

Passo a passo:

1. Clique em File → New → Java Project.

Dê o nome do projeto e desmarque Module – Create module-info.java file

Clique no botão Finish.

55
CAPÍTULO 2 • Comandos da linguagem Java

2. Com o botão direito do mouse no nome do projeto (janela criada à esquerda), clique
em New → Class.

Aparecerá uma janela onde deverá ser escrito o nome da classe (Name: ) e depois,
deverá ser marcada a opção public static void main(String [] args). Por fim, clique
em Finish.

3. Aparecerá um arquivo .java com a classe e o método main.

4. Copie o conteúdo da main dos exemplos e teste!

Exemplo: Programa para ler um valor inteiro e dizer se o valor é par ou ímpar.

import java.util.Scanner;

public class TestaParImpar {

public static void main(String[] args) {

int num;

Scanner teclado = new Scanner(System.in);

System.out.print(“Digite um valor inteiro: “);

num = teclado.nextInt();

if (num % 2 == 0)

System.out.println(num + “ eh par”);

else

System.out.println(num + “ eh impar”);

}//fim main

}//fim classe

Observações:

» Acentos estão sendo evitados para impressão na tela.

56
Comandos da linguagem Java • CAPÍTULO 2

» O teste do if verifica o resto da divisão de um número por 2. Sabe-se que um


número é par se o resto da divisão dele por 2 é zero. Se o número não for par, ele só
poderá ser ímpar. No caso de ser ímpar, o resto da divisão do número por 2 é 1.

Exemplo: Programa para ler um valor inteiro e dizer se ele é múltiplo de 3.

import java.util.Scanner;

public class Multiplo3 {

public static void main(String[] args) {

int num;

Scanner teclado = new Scanner(System.in);

System.out.print(“Digite um valor inteiro: “);

num = teclado.nextInt();

if (num % 3 == 0)

System.out.println(num + “ eh multiplo de 3”);

else

System.out.println(num + “ nao eh multiplo de 3”);

}//fim main

}//fim classe

Exemplo: Programa para ler um valor inteiro e dizer se ele é múltiplo de 3 e de 5.

import java.util.Scanner;

public class Multiplo3_5 {

public static void main(String[] args) {

int num;

57
CAPÍTULO 2 • Comandos da linguagem Java

Scanner teclado = new Scanner(System.in);

System.out.print(“Digite um valor inteiro: “);

num = teclado.nextInt();

if (num % 3 == 0 && num % 5 == 0 )

System.out.println(num + “ eh multiplo de 3 e de 5”);

else

System.out.println(num + “ nao eh multiplo de 3 e de 5”);

}//fim main

}//fim classe

Exemplo: Programa para imprimir os pares de 1 até 50.

Observação: Se fosse para imprimir ímpares, o teste do if nas soluções 1 e 2 a seguir,


poderia ser:

if (i % 2 == 1)

ou

if (i % 2 != 0)

//Solução 1: com for e com teste do if

public class Pares {

public static void main(String[] args) {

int i;

System.out.println(“Numeros pares de 1 a 50”);

for (i = 1; i <= 50; i++)

if (i % 2 == 0)

System.out.println(i);

} //fim main

} //fim classe

58
Comandos da linguagem Java • CAPÍTULO 2

Observação: A variável i poderia ter sido inicializada com 2, visto que 1 é ímpar.

//Solução 2: com while e com teste do if

public class Pares {

public static void main(String[] args) {

int i;

System.out.println(“Numeros pares de 1 a 50”);

i = 1;

while (i <= 50) {

if (i % 2 == 0) //testa se é par

System.out.println(i);

i++; //note que i++; está fora do if

} //fim while

} //fim main

} //fim classe

//Solução 3: com for e sem teste do if. Note o uso do operador +=

import java.util.Scanner;

public class Pares {

public static void main(String[] args) {

int i;

59
CAPÍTULO 2 • Comandos da linguagem Java

System.out.println(“Numeros pares de 1 a 50”);

for (i = 2; i <= 50; i += 2)

System.out.println(i);

} //fim main

} //fim classe

Observação: i += 2 equivale a i = i + 2

Sintetizando

Síntese do capítulo:

» Os comandos de decisão são: if, if/else, switch.

» O comando if/else pode ser encadeado ou aninhado.

» O operador ternário ? : permite reescrever trechos com if/else.

» Para terminar o switch usa-se o comando break.

» O default é opcional no switch.

» while, for e do...while são comandos de repetição.

» No while o teste lógico é no início.

» No do...while o teste lógico é no final.

» Pode-se usar o comando break para terminar um loop com qualquer um dos três comandos.

» O comando continue força o início da próxima interação do loop de um comando de repetição.

60
CAPÍTULO
CONCEITOS E IMPLEMENTAÇÃO
USANDO ORIENTAÇÃO A OBJETOS 3
Introdução do capítulo

De forma simplificada, podemos dizer que desenvolver um sistema é criar uma solução
computacional para um problema do mundo real.

O sistema orientado a objetos pressupõe que o mundo é composto por objetos, que integram
dados e funções. Os sistemas são criados a partir de objetos que existem no domínio do
problema, isto é, os sistemas são modelados como um conjunto de objetos que interagem
entre si.

A Orientação a Objeto (OO) é um paradigma de análise, projeto e programação baseado na


interação entre diversas unidades de software chamadas objetos.

Saiba mais

Paradigma significa modelo ou padrão.

Objetivos do capítulo

» Apresentar algumas das principais características de OO: classificação, abstração e


encapsulamento.

» Aplicar os conceitos de OO na implementação das primeiras classes.

3.1 Classes e objetos

Um objeto é a representação computacional de um elemento ou processo do mundo real.


Vejamos alguns exemplos:

martelo carro piloto casa

disciplina computador cliente aluno

61
CAPÍTULO 3 • Conceitos e Implementação usando Orientação a Objetos

Figura 20. Objeto casa.

Fonte: https://pixabay.com/pt/vectors/casa-%c3%adcone-s%c3%admbolo-arquitetura-2492054/.

Figura 21. Objeto carro.

Fonte: https://pixabay.com/pt/vectors/bmw-carro-roadster-carro-esporte-158703/.

Para cada um dos objetos citados, é possível pensar nas características e nos comportamentos.

Cada característica é chamada de atributo do objeto.

Alguns exemplos de atributos do objeto carro:

» Cor

» Marca

» Ano de fabricação

» Tipo de combustível

É possível associar um conjunto de valores aos atributos. No caso do objeto carro, a cor do
carro pode ser vermelha, azul, verde, entre outras.

Cada comportamento é chamado de método do objeto.

Um comportamento representa uma reação ou resposta de um objeto a uma ação ou evento


do mundo real.

62
Conceitos e Implementação usando Orientação a Objetos • CAPÍTULO 3

Alguns exemplos de comportamentos do objeto carro:

» Acelerar;

» Frear;

» Ligar farol;

» Desligar farol;

» Estacionar.

Atenção

Figura 22. Atributos e métodos.

Mundo real Mundo computacional

característica atributo

comportamento método

Fonte: elaborada pela autora.

Objetos com as mesmas características e comportamentos são agrupados em uma classe,


sendo que cada classe define um conjunto infinito de objetos.

Exemplo: Imagine os alunos de uma instituição de ensino.

» Que características você consegue observar nesses alunos?

› Nome: João, Maria, André, Ana, Felipe, Cátia, ...

› CPF: 823745967-80, 674124745-56, 278452872-78, ...

› Data de nascimento: 01/03/1997, 25/06/1995, ...

› Matrícula: 2016145234, 2015264532, 2015285631, ...

etc.

63
CAPÍTULO 3 • Conceitos e Implementação usando Orientação a Objetos

Observe que, a partir desse conjunto de atributos podemos representar todos os alunos.

» Que comportamentos podemos observar nesses alunos?

› Inscrever em disciplina

› Trancar matrícula

› Consultar nota

› Consultar frequência

etc.

Note que esses comportamentos são comuns a todos os alunos.

Figura 23. Objetos Aluno. Figura 24. Classe Aluno.

Fonte: https://www.shutterstock.com/pt/image-photo/happy-young-
university-students-studying-books-522554425. Fonte: elaborada pela autora.

Classificação

A criação da classe Aluno a partir dos objetos Aluno ocorre por um processo de abstração,
de acordo com as características (atributos) e os comportamentos (métodos) dos objetos
em questão.

Figura 25. Abstraindo para criar a classe.

Objetos Aluno Classe Aluno

abstrair
em
Fonte: elaborada pela autora.

64
Conceitos e Implementação usando Orientação a Objetos • CAPÍTULO 3

Note que:

» A classe descreve os atributos e os métodos de um conjunto de objetos.

» A classe é um molde a partir do qual todos os objetos daquela classe são criados.

» Cada objeto pertence a uma única classe.

» A classe é o bloco básico para a construção de programas OO.

Quando criamos um objeto a partir de uma classe, dizemos que temos uma instância da
classe.

Figura 26. Classe Aluno e algumas instâncias.

Fonte: elaborada pela autora.

Importante

Um objeto tem valores associados aos atributos da classe à qual ele pertence.

Abstração é um processo para identificar as características (atributos) e os comportamentos


(métodos) de um objeto, de acordo com a perspectiva de quem observa esse objeto e do
contexto onde ele será usado.

Exemplo: Considerando alunos e um sistema de controle acadêmico, quais das características


indicadas a seguir são relevantes?

» Nome

» CPF

» Data de nascimento

65
CAPÍTULO 3 • Conceitos e Implementação usando Orientação a Objetos

» Matrícula

» Altura

» Cor do cabelo

» Cor dos olhos

Como o contexto do objeto é um sistema acadêmico, temos que altura, cor do cabelo ou cor
dos olhos são irrelevantes. Então, para atributos dos objetos de uma classe Aluno teremos,
das possibilidades listadas acima, o nome, o CPF, a data de nascimento e a matrícula.

Atenção

As classes são os elementos básicos para construção de programas OO em linguagens como C++, Java e C#. Assim, para
construir um programa OO devemos, inicialmente, identificar as classes que fazem parte do problema que estamos tentando
resolver. As técnicas para identificação de classes fogem do escopo deste livro.

Exemplo: Imagine que desejamos implementar um editor gráfico que irá manipular figuras
geométricas em um plano cartesiano, como, por exemplo, retângulo, círculo, triângulo etc.
Quais as classes candidatas para esse projeto?

» Retângulo.

» Círculo.

» Triângulo.

Tomando por base a implementação da classe Retângulo:

Quais as características de um retângulo?

» Base, altura, posição (x,y) no plano, cor da borda, cor de preenchimento, etc.

Que operações gostaríamos de realizar com o retângulo?

» Desenhar, mover, rodar, redimensionar, etc.

Então, vamos começar definindo a classe Retangulo!

Para criar uma classe precisamos definir o lugar onde iremos colocar essa classe. No Java,
esse lugar é chamado de pacote.

Podemos imaginar o pacote como sendo um diretório ou uma pasta onde colocamos a
classe, sendo que podemos definir quantos pacotes quisermos e ainda, escolher o seu
nome, pois o nome do pacote é definido pelo próprio desenvolvedor.

66
Conceitos e Implementação usando Orientação a Objetos • CAPÍTULO 3

De acordo com a convenção adotada no Java, os nomes dos pacotes devem ter somente
letras minúsculas.

Da mesma forma que podemos ter uma hierarquia de pastas, também podemos ter uma
hierarquia de pacotes. Assim, quando um pacote está dentro de outro, usamos o ponto (.)
para definir a hierarquia de pacotes.

Figura 27. Exemplo de pacote.

Fonte: elaborada pela autora.

Na figura anterior, é mostrado o exemplo da classe Pessoa que está dentro do pacote java.
mhs.unitri.javapos.

Vimos o que é pacote, mas precisamos saber das possibilidades em relação às classes.
Como uma classe pode ser?

» public, private ou package (em termos de visibilidade)

» abstract

» final

Alguns desses tipos serão vistos posteriormente.

Com relação à visibilidade da classe, temos:

» public: é visível por qualquer outra classe em qualquer pacote.

» private: só é visível no arquivo onde foi criada.

» package: só é visível por outras classes do mesmo pacote. É a visibilidade default


(não precisa escrever package).

Voltando para a classe Retangulo, podemos ter:

package principal;

public class Retangulo {

67
CAPÍTULO 3 • Conceitos e Implementação usando Orientação a Objetos

Preferencialmente, toda classe deve ser declarada dentro de um pacote.

Por ser pública, a classe Retangulo é visualizada por todas as demais classes do sistema.

Importante

Quando a linha do package não é escrita, o pacote é o default.

Agora, é preciso adicionar os atributos e métodos à classe Retangulo!

3.2 Encapsulamento

Uma classe encapsula atributos e métodos ocultando os detalhes de implementação dos


objetos. Ou seja, o encapsulamento consiste em mostrar o que pode ser feito sem informar
como.

Princípio do desenvolvimento orientado a objetos:

» Um objeto deve esconder seus atributos de outros objetos, ou seja, os atributos de


uns objetos não podem ser manipulados diretamente por outros objetos.

» Os atributos só podem ser alterados ou consultados pelos métodos do objeto.

3.3 Atributos e construtor

Anteriormente, vimos que um atributo representa a característica do objeto. Então, como


representar os atributos de uma classe? Basicamente, declarando-os e indicando a sua
visibilidade.

A visibilidade de um atributo pode ser:

» public: pode ser livremente lido ou alterado por qualquer classe.

» private: só pode ser lido ou alterado na própria classe, ou seja, esse atributo não é
visível fora da classe.

» package: só pode ser lido ou alterado pelas classes do mesmo pacote. É a visibilidade
default (não precisa escrever package).

» protected: é um nível intermediário entre o public e o private. Um atributo protected


pode ser acessado na própria classe, nas classes filhas e por outras classes no mesmo
pacote, filhas ou não. Será usado ao estudarmos herança.

68
Conceitos e Implementação usando Orientação a Objetos • CAPÍTULO 3

Saiba mais

Um atributo ainda pode ser static e/ou final.

Ser static significa que o atributo é da classe e ser final significa que o atributo é constante, ou seja, seu valor inicial não pode
ser alterado.

No caso da classe Retangulo, vamos considerar simplificadamente, dois atributos: base e


altura, ambos do tipo double. Além disso, é importante notar a questão da visibilidade dos
atributos que, nesse caso, serão private.

public class Retangulo {

private float base;

private float altura;

Importante

» Pelo princípio do encapsulamento, que é uma das características de OO, os atributos não devem ser visíveis por nenhum
objeto que não seja um objeto da própria classe ou de uma classe descendente ou filha (herança).

» Assim, devemos declarar nossos atributos sempre como protected ou private.

» Veremos herança em outro capítulo, quando será ensinado protected na prática.

Um atributo pode ser, explicitamente, inicializado da mesma forma que as variáveis. Note
que os atributos da classe Retangulo não foram inicializados. O que acontece neste caso? A
JVM (Java Virtual Machine) os inicializa, automaticamente, com valores default (padrão).

Importante

Quais os valores default usados para inicializar os atributos?

» boolean: false

» char: ‘\0’ (caracter nulo)

» byte, short, int, long, float, double: 0

» referência para outro objeto: null

69
CAPÍTULO 3 • Conceitos e Implementação usando Orientação a Objetos

A classe é um molde a partir do qual podemos representar objetos reais, como criar os objetos
da classe Retangulo que terão os atributos base e altura?

Para criar objetos é preciso que a classe tenha um construtor.

Vemos que, no caso da classe Retangulo, não há nada escrito além dos atributos. Então, qual
será o mecanismo para criar objetos desta classe?

Usar o construtor default ou padrão da classe!

É o construtor da classe Retangulo que permitirá que retângulos de diferentes bases e alturas
sejam criados ou construídos.

Saiba mais

Veremos, em outro momento, que é possível escrever código no construtor para dizer que queremos criar objetos com
valores não default para seus atributos.

Como é o construtor default ou padrão da classe Retangulo, que neste caso, não precisa ser
explicitado?

public Retangulo() {

Atenção

» O nome do construtor é sempre igual ao nome da classe.

» Os parênteses estão vazios, o que significa que o construtor não recebe nada, ou seja, não tem parâmetros.

» Dentro das chaves nada está escrito, visto que os atributos da classe serão inicializados com valores default.

A classe com o construtor padrão ou default:

public class Retangulo {

//atributos privados

private float base;

private float altura;

70
Conceitos e Implementação usando Orientação a Objetos • CAPÍTULO 3

//construtor padrão ou default

public Retangulo() {

Agora veremos como criar retângulos, ou seja, objetos ou instâncias da classe Retangulo.
Para isso, iremos trabalhar na main. Lembra que é pela main que a execução começa? Note
que a main sempre será escrita dentro de uma classe pública. Neste caso, será a classe
TestaRetangulo.

public class TestaRetangulo {


public static void main(String[] args) {

Retangulo r; Define uma variável r do tipo Retangulo.


Inicialmente, essa variável não referencia
r = new Retangulo(); nenhum objeto, pois o objeto ainda não foi
} criado.

Cria um objeto r da classe Retangulo, chamando o construtor no trecho


Retangulo(). Note o uso do operador new. É ele que permite a criação do
objeto ou instância da classe.

Importante

» O operador new é usado para criar um objeto, ou seja, uma instância de uma classe.

» Ao declararmos uma variável do tipo de uma classe não estamos criando o objeto em si, mas somente uma referência para
o objeto.

» Em Retangulo r; ocorre o que ilustra a figura a seguir:

Figura 28. Ao declarar r.

?
Fonte: elaborada pela autora.

71
CAPÍTULO 3 • Conceitos e Implementação usando Orientação a Objetos

Ou seja, r referencia uma área de memória, sem ainda se ter um objeto da classe Retangulo.

» Em r = new Retangulo(); a variável r passa a referenciar o objeto criado. E como o construtor é o default, os valores dos
atributos do objeto são inicializados, na sua criação, com zero.

Figura 29. Objeto ou instância r com base e altura zero.

base = 0.0
altura = 0.0

Fonte: elaborada pela autora.

» Um retângulo com base e altura zero deve, após a sua criação, ter os valores de seus atributos ajustados para valores
realistas. Ou seja, valores maiores que zero. Mas como fazer isso? Usando métodos de acesso.

» Note que:

Retangulo r;

r = new Retangulo();

equivale a fazer Retangulo r = new Retangulo();

Podem existir várias formas diferentes de criar um objeto. Assim, podemos ter vários
construtores diferentes para uma mesma classe.

Sintaxe simplificada de construtores:

public NomeDaClasse( <parâmetros> ) {

<corpo do construtor>

Observe que:

» Construtores não tem nenhum tipo de retorno.

» Construtores podem receber parâmetros que são usados na inicialização do objeto.

Vamos escrever um construtor que receba, como parâmetros, os valores da base e da altura:

72
Conceitos e Implementação usando Orientação a Objetos • CAPÍTULO 3

public Retangulo(int x, int y) {


base = x;
altura = y;
} Parâmetros: x e y
Os parâmetros poderiam ter outros nomes, desde
que seguissem a regra para identificadores
Atributos: base e altura

Ao se instanciar a classe Retangulo, ou seja, ao se criar um objeto ou instância da classe


Retangulo, devem ser passados dois valores: o primeiro irá definir o valor da base e o
segundo será atribuído à altura.

Como criar, por exemplo, um retângulo s com base 3.5 e altura 118.3 usando o construtor
acima? Basta escrever na main:

Retangulo s = new Retangulo(3.5, 118.3);

Figura 30. Objeto ou instância s com base e altura previamente definidos.

base = 3.5
altura = 118.3

Fonte: elaborada pela autora.

Atenção! Se fizermos como mostrado na figura a seguir, ocorrerá erro!

Figura 31. Erro nas atribuições.

Fonte: elaborada pela autora.

É preciso identificar quais são os atributos do objeto e quais são os parâmetros do


construtor. Para isso, vamos usar a palavra reservada this, que é uma referência para o
objeto, que nesse caso, está sendo construído.

73
CAPÍTULO 3 • Conceitos e Implementação usando Orientação a Objetos

Acertando com a referência this, temos:

public Retangulo(int base, int altura) {

this.base = base;
this.altura = altura;

} A referência this é usada para informar que


estamos acessando os atributos ao invés dos
parâmetros.

Veja como estão as classes Retangulo e TestaRetangulo até o momento.

public class Retangulo {

//atributos privados

private double base;

private double altura;

//construtor padrão ou default

public Retangulo() { }

//outro construtor

public Retangulo(int base, int altura) {

this.base = base;

this.altura = altura;

} //fim da classe Retangulo

74
Conceitos e Implementação usando Orientação a Objetos • CAPÍTULO 3

public class TestaRetangulo {

public static void main(String[] args) {

Retangulo r = new Retangulo();

Retangulo s = new Retangulo(3.5, 118.3);

} //fim main

} //fim da classe TestaRetangulo

Ambas as classes Retangulo e TestaRetangulo fazem parte de um mesmo projeto de nome


TestaRetangulo.

3.4 Métodos de acesso

Como acessar e alterar os valores dos atributos do objeto r que foi construído com base e
altura nulas, já que os atributos da classe Retangulo são privados?

A resposta é:
Métodos de acesso!

Métodos de acesso são usados para obter ou alterar atributos e usam os seguintes padrões:

public tipo get<nome do atributo>()

return atributo;

75
CAPÍTULO 3 • Conceitos e Implementação usando Orientação a Objetos

public void set<nome do atributo>(tipo novoValor)

atributo = novoValor;

Observe que os métodos getters irão retornar um valor de acordo com o tipo indicado
antes do nome do método. Já os setters não retornarão nada (void) e farão atribuições aos
atributos do objeto, pois recebem valor(es) passado(s) por parâmetro(s).

No caso da classe Retangulo, precisamos ter acesso à base e à altura para manipular seus
valores, seja alterando-os ou apenas usando-os. Nesse caso, teremos os métodos:

» getAltura: para obter o valor da altura.

» getBase: para obter o valor da base.

» setAltura: modificar o valor da altura.

» setBase: modificar o valor da base.

Veja a classe Retangulo atualizada, com mais esses métodos:

public class Retangulo {

//atributos privados

private double base;

private double altura;

//construtor padrão ou default

public Retangulo() {

76
Conceitos e Implementação usando Orientação a Objetos • CAPÍTULO 3

//outro construtor...não padrão

public Retangulo(double base, double altura) {

this.base = base;

this.altura = altura;

//métodos de acesso

public void setAltura(double altura) { this.altura = altura; }

public void setBase(double base) { this.base = base; }

public double getAltura() { return this.altura; }

public double getBase() { return this.base; }

} //fim da classe Retangulo

Agora é possível alterar e obter os valores dos objetos r e s, criados na classe TestaRetangulo.
Vejamos algumas possibilidades de uso para os getters e setters:

public class TestaRetangulo {

public static void main(String[] args) {

Retangulo r = new Retangulo(); // cria o retângulo r com base e altura zero

77
CAPÍTULO 3 • Conceitos e Implementação usando Orientação a Objetos

Retangulo s = new Retangulo(3.5, 118.3); // cria o retângulo s

//Imprimindo a base e altura de r antes de alterá-los

System.out.println(“Com os valores default => Base de r = “ + r.getBase()

+ “ Altura de r = “ + r.getAltura());

//Alterando os valores dos atributos de r

r.setAltura(4.0);

r.setBase(2.5);

//Imprimindo os dados de r e s

System.out.println(“Apos alterar => Base de r = “ + r.getBase()

+ “ Altura de r = “ + r.getAltura());

System.out.println(“Base de s = “ + s.getBase() + “ Altura de s = “

+ s.getAltura());

//baseS e alturaS são duas variáveis locais à main

double baseS = s.getBase();

double alturaS = s.getAltura();

//Imprimindo a área do retângulo s

System.out.println(“Area de s = “ + (baseS * alturaS));

} //fim da main

} //fim da classe TestaRetangulo

78
Conceitos e Implementação usando Orientação a Objetos • CAPÍTULO 3

Importante

Para chamar um método de uma classe para um objeto da classe, usa-se a regra:

objeto.método

No programa acima tivemos as chamadas para os setters e os getters para os objetos r e s da classe Retangulo.

3.5 Métodos de instância

Além dos getters e setters, uma classe tem outros métodos que permitirão que os objetos
ou instâncias da classe realizem as operações dentro do contexto do problema.

Imagine uma classe Robo, cujos atributos, para simplificar, sejam:

» marca

» numSerie (número de série)

» ano (ano de fabricação)

» preco (preço do robô)

Quais seriam os comportamentos desse robô, se fosse um robô voltado para tarefas
domésticas? Lavar, passar, cozinhar, limpar... Dessa forma, é possível ter, por exemplo, os
seguintes métodos:

» lavar;

» limpar;

» cozinhar;

» passar.

Voltando ao exemplo da classe Retangulo, que comportamentos os objetos ou instâncias


da classe podem ter?

Mover, desenhar, redimensionar,

calcular a área, calcular o perímetro,

imprimir os valores da base e da altura etc.

Com os atributos que usamos, vamos escrever os seguintes métodos: calcularArea,


calcularPerimetro e imprimirDados. Observe a seguir, a versão mais atualizada das classes
Retangulo e TestaRetangulo:

79
CAPÍTULO 3 • Conceitos e Implementação usando Orientação a Objetos

public class Retangulo {

//atributos privados

private double base;

private double altura;

//construtor padrão ou default

public Retangulo() { }

//outro construtor...não padrão

public Retangulo(double base, double altura) {

this.base = base;

this.altura = altura;

//métodos de acesso

public void setAltura(double altura) { this.altura = altura; }

public void setBase(double base) { this.base = base; }

public double getAltura() { return this.altura; }

public double getBase() { return this.base; }

80
Conceitos e Implementação usando Orientação a Objetos • CAPÍTULO 3

//outros métodos

public double calcularArea() { return base * altura; }

public double calcularPerimetro() { return 2 * base + 2 * altura; }

public void imprimirDados() {

System.out.printf(“Base = %.2f Altura = %.2f”, base, altura);

} //fim da classe Retangulo

public class TestaRetangulo {

public static void main(String[] args) {

Retangulo r = new Retangulo();

Retangulo s = new Retangulo(3.5, 118.3);

//Imprimindo a base e altura de r antes de alterá-los

System.out.println(“Com os valores default => Base de r = “ + r.getBase()

+ “ Altura de r = “ + r.getAltura());

81
CAPÍTULO 3 • Conceitos e Implementação usando Orientação a Objetos

//Alterando os valores dos atributos de r

r.setAltura(4.0);

r.setBase(2.5);

//Imprimindo os dados de r e s

System.out.println(“Apos alterar => Base de r = “ + r.getBase()

+ “ Altura de r = “ + r.getAltura());

System.out.println(“Base de s = “ + s.getBase() + “ Altura de r = “

+ s.getAltura());

//baseS e alturaS são duas variáveis locais à main

double baseS = s.getBase();

double alturaS = s.getAltura();

//Imprimindo a área do retângulo s

System.out.println(“Area de s = “ + (baseS * alturaS));

//Imprimindo os dados dos retângulos r e s

System.out.println(“\nDados do retangulo r “);

r.imprimirDados();

System.out.println(“\nDados do retangulo s “);

s.imprimirDados();

//Imprimindo as áreas e os perímetros, chamando os métodos

82
Conceitos e Implementação usando Orientação a Objetos • CAPÍTULO 3

System.out.println(“\n\nArea de r = “ + r.calcularArea());

System.out.println(“Area de s = “ + s.calcularArea());

System.out.println(“\n\nPerimetro de r = “ + r.calcularPerimetro());

System.out.println(“Perimetro de s = “ + s.calcularPerimetro());

} //fim da main

} //fim da classe TestaRetangulo

3.6 Sobrecarga de métodos e de construtores

Java permite que tenhamos, na mesma classe, métodos com o mesmo nome, mas com
parâmetros diferentes. Isso é chamado sobrecarga de métodos (overload de métodos).

No exemplo da classe Retângulo, podemos definir um método para redimensionar o


retângulo:

public void redimensionar(double sx, double sy) {

if (sx > 0 && sy > 0) {

base = (int) (sx / 100 * base);

altura = (int) (sy / 100 * altura);

Mas é possível escrever, na mesma classe Retangulo, um outro redimensionar que receba
valores inteiros:

public void redimensionar(int larg, int alt) {

if (larg > 0 && alt > 0) {

largura = larg;

83
CAPÍTULO 3 • Conceitos e Implementação usando Orientação a Objetos

altura = alt;

Os dois métodos para redimensionar o retângulo têm o mesmo nome, mas se diferenciam
pelos tipos dos parâmetros: double e int.

A linguagem Java não confunde os dois métodos porque eles têm assinaturas diferentes.

Assinatura diferente significa que os métodos têm:

» quantidades de parâmetros diferentes,

» tipos dos parâmetros diferentes, ou

» ordem dos parâmetros diferente.

Atenção

E no seguinte caso:

public void redimensionar(int larg, int alt) { ... }

public boolean redimensionar(int larg, int alt) { ... }

Haverá erro de compilação. Apesar de um método não retornar nada (void) e o outro retornar um boolean, ambos recebem
dados inteiros. Por essa razão, são considerados métodos iguais.

Além de sobrecarga de métodos, é possível haver sobrecarga de construtores. Na classe


Retangulo foram escritos dois construtores que se diferenciavam pelos parâmetros: um
nada recebia e o outro recebia dois valores do tipo double (base e altura). Reveja apenas o
trecho da classe com os dois construtores:

public class Retangulo {

//atributos privados

private double base;

private double altura;

//construtor padrão ou default

public Retangulo() { }

84
Conceitos e Implementação usando Orientação a Objetos • CAPÍTULO 3

//outro construtor...não padrão

public Retangulo(double base, double altura) {

this.base = base;

this.altura = altura;

//métodos de acesso e outros métodos...

} //fim da classe Retangulo

3.7 Classes pré-definidas: Math e String

No Java existe uma classe bastante usada que implementa funções matemáticas chamada
Math. Todos os métodos dessa classe são estáticos (static), isto é, não dependem de
nenhum objeto para serem executados.

public class Math {

public static double sqrt(double x) { ... }

public static long round(double x) { ... }

public static double pow(double x, double y) { ... }

//Outros métodos

Importante

» sqrt é um método estático (static) que deve receber um valor double (veja o parâmetro x) e retornar um valor double.

» round também é estático, recebe um valor double e retorna um long.

» pow recebe dois valores do tipo double e retorna um valor double.

A principal diferença entre os métodos estáticos e os métodos de instância está na sua


chamada.

85
CAPÍTULO 3 • Conceitos e Implementação usando Orientação a Objetos

Importante

Nos métodos estáticos não precisamos do objeto para chamar o método.

Em vez disso, usamos o próprio nome da classe para denominá-los.

Exemplos:

double x = 12.2;

double y = Math.sqrt(x); // calcula a raiz quadrada de x

long z = Math.round(y); // arredonda o valor de y

Atenção

Note como fazer a chamada de um método static: Classe.Método

Figura 32. Métodos da classe Math.

Fonte: elaborada pela autora.

Uma outra classe super importante é a String. A classe String é pré-definida e está na
biblioteca de classes da linguagem. Portanto, note que a linguagem Java não possui um
tipo primitivo string como em algumas outras linguagens de programação.

A declaração de um objeto String segue o mesmo padrão de declaração das variáveis de


tipos básicos:

86
Conceitos e Implementação usando Orientação a Objetos • CAPÍTULO 3

String mensagem; A concatenação de strings é feita


String nome = "Joao da Silva"; com o operador +
String saudacao = "Olá " + nome;
String vazia = "";

Importante

Repare que não precisamos do operador new para criar o objeto String. O Java chama implicitamente esse operador.

A classe String tem mais de 60 métodos para manipulação de strings. Alguns dos métodos
mais usados são definidos na figura a seguir:

Figura 33. Métodos da classe String.

Fonte: elaborada pela autora.

Exemplo: Considere o trecho em Java a seguir:

String str = “Programação Orientada a Objetos”;

char c;

boolean ok;

c = str.charAt(2);

c = str.charAt(7);

ok = str.isEmpty();

87
CAPÍTULO 3 • Conceitos e Implementação usando Orientação a Objetos

Cada caractere possui uma posição dentro da string, que é, na verdade, o índice do elemento.
O 1º caractere está na posição 0, o 2º caracter na posição 1, o 3º caracter na posição 2 etc.
Então, podemos visualizar que em

Programação Orientada a Objetos

P está na posição 0, r está na posição 1, o está na posição 2, g está na posição 3, e assim


sucessivamente.

Analisando o trecho anterior, temos:

c = str.charAt(2); // c recebe o elemento de índice 2 de str, que é ‘o’

c = str.charAt(7); //c recebe o elemento de índice 7 de str, que é ‘a’

ok = str.isEmpty(); // ok recebe false

Exemplo: Considere o trecho escrito em Java a seguir:

String str = “Programação Orientada a Objetos”;

int p;

p = str.indexOf(‘a’);

p = str.indexOf(‘O’);

p = str.indexOf(‘x’);

p = str.lastIndexOf(‘a’);

p = str.length();

String nova = str.replace(‘o’, ‘-’);

Analisando o trecho anterior, temos:

p = str.indexOf(‘a’); // p recebe 5

p = str.indexOf(‘O’); // p recebe 12

p = str.indexOf(‘x’); // p recebe -1

p = str.lastIndexOf(‘a’); // p recebe 22

p = str.length(); // p recebe 31

88
Conceitos e Implementação usando Orientação a Objetos • CAPÍTULO 3

String nova = str.replace(‘o’, ‘-’); // nova é “Pr-gramaçã- Orientada a Objet-s”

Exemplo: Considere os trechos a seguir:

String str = “Programação Orientada a Objetos”;

boolean ok;

ok = str.startsWith(‘Progra’);

ok = str.startsWith(‘grama’);

System.out.println(str.toUpperCase());

System.out.println(str.substring(0, 6));

System.out.println(str.substring(3, 8));

Analisando o trecho anterior, temos:

ok = str.startsWith(‘Progra’); // ok recebe true

ok = str.startsWith(‘grama’); // ok recebe false

System.out.println(str.toUpperCase());

// é impresso “PROGRAMAÇÃO ORIENTADA A OBJETOS”

System.out.println(str.substring(0, 6)); //é impresso “Progra”

System.out.println(str.substring(3, 8)); //é impresso “grama”

Exemplo: Considere os trechos abaixo em Java:

89
CAPÍTULO 3 • Conceitos e Implementação usando Orientação a Objetos

String nome = “ João da Silva “;

System.out.println(nome.trim());

System.out.println(nome.trim().toUpperCase());

Analisando o trecho anterior, temos:

System.out.println(nome.trim()); // É impresso: “João da Silva”

System.out.println(nome.trim().toUpperCase());

// É impresso “JOÃO DA SILVA”

Importante

» Strings, em Java, são imutáveis.

Isso significa dizer que, uma vez criada, não podemos alterar o conteúdo de uma string.

» Quando usamos um método que “altera” a string, na realidade estamos criando um outro objeto na memória.

Exemplo:

"Programação Orientada a Objetos"

String disciplina = "Programação Orientada a Objetos";

String maiuscula = disciplina.toUpperCase();

"PROGRAMAÇÃO ORIENTADA A OBJETOS"

String outra = maiuscula.replace(' ', '-');

"PROGRAMAÇÃO-ORIENTADA-A-OBJETOS"

Um detalhe muito importante da manipulação de strings é em relação à comparação de


strings. Como strings são objetos, se usarmos os operadores relacionais (==, !=, >, <, >= ou <=)
estaremos comparando as referências para as strings e não o conteúdo delas.

Para realizar a comparação do conteúdo devemos usar os métodos:

» equals()

» equalsIgnoreCase()

90
Conceitos e Implementação usando Orientação a Objetos • CAPÍTULO 3

» compareTo()

» compareToIgnoreCase()

Exemplo: Seja o trecho em Java. Para testar, não esqueça de importar o pacote da classe
Scanner.

Scanner t = new Scanner(System.in);


String nome1 = t.nextLine();
String nome2 = t.nextLine();
String nome3 = nome1; Com o método equals() estamos
if (nome1.equals(nome2)) comparando os conteúdos.
System.out.println("Igual"); Nesse caso vai imprimir "Igual"
else
System.out.println("Diferente");

Figura 34. Usando == e != com string.

nome1
"Joao" nome1 == nome3

nome3
nome1 != nome2
"Joao"

nome2

Fonte: elaborada pela autora.

Sintetizando

Síntese do capítulo:

» Classe é um molde a partir do qual criamos objetos ou instâncias.

» Todo objeto tem atributos e métodos que serão definidos na classe a qual o objeto pertence.

» Quanto à visibilidade, uma classe pode ser public, private ou package.

» As classes podem pertencer a um pacote, mas quando o pacote não é definido temos o default.

» Uma das características da Orientação a Objetos é o encapsulamento.

» Quanto à visibilidade, os atributos podem ser public, private, package ou protected.

» O construtor, sendo default ou não, permite a criação dos objetos.

» O operador new é usado para a criação de objetos.

» Para acessar os atributos privados de uma classe podemos contar com os getters e setters.

» Métodos de instância são usados com objetos criados de alguma classe.

» A sobrecarga (overload) pode ser de métodos ou de construtores.

» A classe Math tem vários métodos estáticos (static) que realizam as mais variadas tarefas matemáticas, como, por exemplo,
calcular a raiz quadrada, arredondamento etc.

» Para chamar um método static não é preciso instanciar a classe, ou seja, não é preciso criar um objeto da classe.

» A classe String tem um conjunto variado de métodos, como, por exemplo, pôr em letras maíusculas, pôr em minúsculas,
calcular o tamanho da string etc.

91
CAPÍTULO
CLASSES E OBJETOS: UMA VISÃO MAIS
APROFUNDADA 4
Introdução ao capítulo

Neste capítulo você estará diante da criação de programas mais elaborados, através da
aplicação de conceitos mais aprofundados como, por exemplo, herança e polimorfismo.
Após este estudo, ficará registrado como a linguagem de programação Java nos permite
reaproveitar código, possibilitando, dessa forma, ganho de produtividade e tempo.

Objetivos do capítulo

» Realizar o estudo de vetor e suas aplicações em programas escritos em Java.

» Apresentar herança e polimorfismo na teoria e na prática usando a linguagem Java.

» Apresentar conceitos mais avançados, tais como classe abstrata e interface, na teoria
e na prática usando a linguagem Java.

4.1 Vetor

Vetor ou array é um agregado de dados homogêneos, ou seja, dados do mesmo tipo.

O vetor é armazenado de forma contígua na memória e o acesso a cada elemento se dá através


do índice do vetor.

Importante

Em Java, vetores são objetos.

Para declarar um vetor, usamos o operador [ ] imediatamente após o tipo desejado. Exemplos:

int [ ] v;

float [ ] nota;

92
Classes e objetos: uma visão mais aprofundada • CAPÍTULO 4

Outra diferença importante é que, ao declarar um vetor, NÃO definimos o seu tamanho. Isso
significa dizer que, ao declarar um vetor, o Java NÃO aloca espaço na memória para o vetor.

float [ ] nota;

NULO

Saiba mais

Outra forma de declarar vetor é colocando os colchetes após o nome da variável.

Exemplo: int[ ] v; é o mesmo que int v[ ];

float[ ] nota; é o mesmo que float nota[ ];

Como vetor é um objeto, precisamos criá-lo com o operador new. É nesse momento que
definimos o seu tamanho. Exemplo:

Figura 35. Exemplo de vetor de números reais.

float[ ] nota;
Aqui definimos o
nota = new float[10]; tamanho do vetor!

0 1 2 3 4 5 6 7 8 9
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

Os elementos do vetor O índice final é sempre


O índice são inicializados o tamanho do vetor –
inicial é automaticamente da 1. No caso, o índice
sempre ZERO. mesma forma que os final é 9.
atributos das classes.

Fonte: elaborada pela autora.

Importante

O tamanho do vetor pode ser definido usando uma

constante, variável ou uma expressão.

93
CAPÍTULO 4 • Classes e objetos: uma visão mais aprofundada

Exemplo: Considere um projeto de nome TesteVetor com apenas uma classe, a classe
TesteVetor. Veja:

import java.util.Scanner;

public class TesteVetor {


public static void main(String[] args) {

Scanner t = new Scanner(System.in);


int tam;
float[ ] v; //declara v como um vetor de float

System.out.print("Qual o tamanho do vetor? ");


tam = t.nextInt();
Cria o vetor v usando como
v = new float[tam];
} //fim main tamanho a variável tam.

} //fim classe TesteVetor

Importante

Uma vez definido o tamanho do vetor com o operador new não podemos mais alterar esse tamanho.

Em algumas linguagens, o índice inicial do vetor pode ser negativo. Em Java, no entanto, os
índices variam de zero em diante. Caso um índice que esteja fora dos limites do vetor seja
acessado, ocorrerá erro.

Exemplo: Seja um trecho em Java:

float [ ] nota;

nota = new float[10]; Erro de execução:


nota[-1] = 7.5; ArrayIndexOutOfBoundsException

nota[10] = 8.0;

Assim como fazemos com variáveis comuns, também podemos inicializar vetores.

tipo[ ] nome = { lista de valores };

onde:

lista de valores é uma lista cujos elementos são separados por vírgula.

94
Classes e objetos: uma visão mais aprofundada • CAPÍTULO 4

Exemplos:

Cria automaticamente
float[ ] nota = { 5.5, 6.5, 7.0, 9.0, 8.0 }; um vetor de 5 posições.

int[ ] idade = { 30, 22, 45, 12, 65, 48, 72 };

Cria automaticamente
um vetor de 7 posições.

Para percorrer individualmente cada elemento do vetor, usamos o comando for.

O atributo length do vetor pode ser usado para recuperar o tamanho do vetor. Não
confunda com o método length() da classe String!

public class Vetor {


public static void main(String[] args) {

int[ ] v = { 2, 4, 6, 8, 10 }; v.length recupera o tamanho


for (int i = 0; i < v.length; i++) do vetor, que é 5 nesse caso.
System.out.println(v[i]);

} //fim da main

} //fim da classe

Existe uma outra sintaxe do comando for para percorrer vetores: o for-each. Essa forma é
usada apenas para ler os dados do vetor, mas não serve para alterar os dados do vetor.

Usando essa nova sintaxe, o programa anterior poderia ser reescrito como:

public class Vetor {


public static void main(String[] args) {

int [ ] v = { 2, 4, 6, 8, 10 }; int indica o tipo dos dados


armazenados no vetor v

for (int n : v)
System.out.println(n); n é uma variável auxiliar que
} percorre o vetor v
}

A cada iteração, a variável


n recebe os valores
armazenados no vetor v,
do primeiro até o último.

95
CAPÍTULO 4 • Classes e objetos: uma visão mais aprofundada

Quadro 4. Passo a passo.

1ª iteração: n = v[0]
imprimir n, ou seja, 2.
2ª iteração: n = v[1]
imprimir n, ou seja, 4.
3ª iteração: n = v[2]
imprimir n, ou seja, 6.
4ª iteração: n = v[3]
imprimir n, ou seja, 8.
5ª iteração: n = v[4]
imprimir n, ou seja, 10.

Fonte: elaborada pela autora.

Além de vetor de tipos primitivos (int, float, char...), como mostrado nos exemplos, é possível
termos vetor de objetos.

Quando usamos um vetor de objetos, ao criar o vetor não estamos criando os objetos em
si, apenas referências para os objetos. Além do vetor, cada objeto deve ser criado com o
operador new.

Exemplo: Considere um projeto de nome EditorGrafico com as classes EditorGrafico e


Retangulo (classe do capítulo anterior).

public class EditorGrafico {

public static void main(String[ ] args) {

Retangulo[ ] r; //declara r como vetor de objetos da classe Retangulo

r = new Retangulo[3]; //cria o vetor r para armazenar até 3 retângulos

//define cada componente do vetor r

r[0] = new Retangulo(40, 20);

r[1] = new Retangulo(20, 20);

r[2] = new Retangulo(10, 30);

96
Classes e objetos: uma visão mais aprofundada • CAPÍTULO 4

Figura 36. Analisando o programa anterior passo a passo.

Retangulo [ ] r;

Ao declararmos o vetor, a variável local r


tem um valor indefinido.

r
indefinido !

r = new Retangulo[3];

Ao criarmos um vetor com 3 posições,


alocamos espaço para referenciar 3
retângulos. Essas referências são
inicializadas com null.
Atenção! Ainda não temos os
retângulos!
r
0 1 2
null null null

r[0] = new Retangulo(40,20);


r
0 1 2

null null

base = 40
altura = 20
Quando criamos o primeiro retângulo,
este passa a ser referenciado por r[0].

r[1] = new Retangulo(20,20);


r[2] = new Retangulo(10,30);

Note que r[1] e r[2] são criados de forma análoga a r[0].

r 0 1 2

base = 40
altura = 20

base = 10
base = 20
altura = 30
altura = 20

Fonte: elaborada pela autora.

97
CAPÍTULO 4 • Classes e objetos: uma visão mais aprofundada

Vamos testar alguns métodos da classe Retangulo com os componentes do vetor r.


Atualizando a classe EditorGrafico, temos:

public class EditorGrafico {

public static void main(String[ ] args) {

Retangulo[ ] r; //declara r como vetor de objetos da classe Retangulo

r = new Retangulo[3]; //cria o vetor r

//define cada componente do vetor r

r[0] = new Retangulo(40, 20);

r[1] = new Retangulo(20, 20);

r[2] = new Retangulo(10, 30);

// Altera a base e altura do terceiro retângulo

r[2].setBase(100);

r[2].setAltura(200);

// Imprimir TODOS os retângulos

for (int i = 0; i < r.length; i++)

r[i].imprimirDados();

} //fim main

} //fim classe

4.2 Relacionamento

Um objeto de uma classe pode estar relacionado a um objeto de outra classe ou a vários
objetos de outra classe. Ou ainda, vários objetos de uma classe podem estar relacionados a
vários objetos de outra classe.

98
Classes e objetos: uma visão mais aprofundada • CAPÍTULO 4

Exemplos:

» Professor leciona disciplina.

» Aluno cursa disciplina.

» Departamento oferece disciplina.

» Cliente faz pedidos.

» Transportadora entrega produtos.

» Ônibus transporta passageiros.

» Carro tem motor.

» Jogador faz parte de time.

» Livro tem capítulos.

Quando falamos que

Carro tem motor.

está sendo dito que Um carro tem um motor. Um objeto da classe Carro está relacionado a
um objeto da classe Motor. Neste caso, podemos pensar em um esboço da classe Carro da
seguinte forma:

public class Carro {

private String modelo;

private int ano;

private Motor motor;

Note, portanto que, na classe Carro temos um atributo da classe Motor.

4.3 Herança e Polimorfismo

Considere as duas classes a seguir:

99
CAPÍTULO 4 • Classes e objetos: uma visão mais aprofundada

Figura 37. Exemplo com as classes Carro e Caminhao.

public class Carro { public class Caminhao {


private String placa; private String placa;
private String modelo private String modelo
private int anoFabricacao; private int anoFabricacao;
private int kilometragem; private int kilometragem;
private int qtdPassageiros; private int cargaMaxima;
private int capacidadeBagagem; private int numeroEixos;

public float calculaConsumo() {...} public float calculaConsumo() {...}


public float calculaIPVA() {...} public float calculaIPVA() {...}
} //fim Carro } //fim Caminhao

Fonte: elaborada pela autora.

Definindo dessa forma, teríamos que representar os atributos e métodos comuns nas duas
classes, o que indica duplicidade de código.

Uma das características da Orientação a Objetos que vem a sanar a questão acima chama-se
herança.

Importante

» Herança é o mecanismo pelo qual classes herdam atributos e métodos através de um relacionamento hierárquico.

» Na herança, temos sempre uma classe definida de forma genérica que, posteriormente, é refinada em classes mais
específicas.

Exemplos:

Um professor é um tipo de funcionário.


Um pentágono é um tipo de polígono.
Um carro é um tipo de veículo.
Um notebook é um tipo de computador.

Classes específicas Classes genéricas

ou subclasses ou superclasses

Atenção

Observe a forma de dizer que uma classe “é um tipo de” outra classe quando configurado o relacionamento hierárquico.

É possível existirem várias classes específicas para uma mesma classe genérica.

Veja os exemplos:

Um professor é um tipo de funcionário.

Uma secretária é um tipo de funcionário.

100
Classes e objetos: uma visão mais aprofundada • CAPÍTULO 4

Um diretor é um tipo de funcionário.

Um pentágono é um tipo de polígono.

Um hexágono é um tipo de polígono.

Um carro é um tipo de veículo.

Um caminhão é um tipo de veículo.

Como dito antes, as classes específicas (filhas ou subclasses) herdam atributos e métodos
da sua classe genérica (mãe ou superclasse). Além disso, as classes específicas podem ter
atributos e métodos somente seus.

No exemplo:

Um carro é um tipo de veículo.

Um caminhão é um tipo de veículo.

A classe Veiculo vai conter os atributos e métodos comuns a todos os veículos e as classes
Carro e Caminhao vão conter os atributos e métodos específicos de carros e caminhões,
respectivamente.

Redefinindo o exemplo anterior usando herança:

Figura 38. Classe Veiculo e suas classes filhas Carro e Caminhao.

public class Veiculo {


protected String placa;
protected String modelo
protected int anoFabricacao;
protected int kilometragem;

public float calculaConsumo() {...}


public float calculaIPVA() {...}
}

public class Carro { public class Caminhao {


private int qtdPassageiros; private int cargaMaxima;
private int capacidadeBagagem; private int numeroEixos;
} }

Fonte: elaborada pela autora.

101
CAPÍTULO 4 • Classes e objetos: uma visão mais aprofundada

Outro exemplo:

Figura 39. Classe Funcionario e suas classes filhas Professor e Diretor.

public class Funcionario {


protected String matricula;
protected float salario;
}

public class Professor { public class Diretor {


private String titulacao; private float bonus;
private int cargaHoraria; }
}

Fonte: elaborada pela autora.

Em Orientação a Objetos, a herança pode ser:

» Simples: se a classe herda de apenas uma superclasse ou classe mãe.

» Múltipla: se a classe herda de diversas superclasses ou classes mães.

Exemplo: Carro anfíbio é um tipo de carro e barco, ao mesmo tempo.

O carro anfíbio tem características


de carro e de barco (herança múltipla).

Importante

A linguagem Java não tem herança múltipla, somente herança simples.

Para definir a herança entre duas classes devemos usar a palavra reservada extends na
definição da subclasse. Veja a sintaxe:

public class <nome da classe> extends <nome da superclasse>

Exemplo: Vejamos as classes Veiculo, Carro e Caminhao.

102
Classes e objetos: uma visão mais aprofundada • CAPÍTULO 4

public class Veiculo {


Os atributos protected, assim como os
protected String placa; atributos private, não são visíveis para
protected String modelo; quem usa a classe.
protected int anoFabricacao; Os atributos protected são visíveis
protected int kilometragem; apenas nas subclasses e classes do
pacote.

public Veiculo(String placa, String modelo,


int anoFabricacao, int kilometragem)
{
this.placa = placa;
this.modelo = modelo;
this.anoFabricacao = anoFabricacao;
this.kilometragem = kilometragem;

} //fim do construtor

} //fim da classe Veiculo

Esboçando a classe Carro: Note que a classe Carro


possui os atributos:
public class Carro extends Veiculo { • placa
• modelo
private int qtdPassageiros; • anoFabricacao
private int capacidadeBagagem; • kilometragem
• qtdPassageiros
} • capacidadeBagagem

Como ficará o construtor da classe Carro, já que carro é um tipo de veículo?

Vejamos a versão final da classe Carro:

public class Carro extends Veiculo {

private int qtdPassageiros;

private int capacidadeBagagem;

public Carro(String placa, String modelo,

int anoFabricacao, int kilometragem,

int qtdPassageiros, int capacidadeBagagem)

103
CAPÍTULO 4 • Classes e objetos: uma visão mais aprofundada

super(placa, modelo, anoFabricacao, kilometragem);

this.qtdPassageiros = qtdPassageiros;

this.capacidadeBagagem = capacidadeBagagem;

} //fim construtor

} //fim classe Carro

Importante

Usamos a notação super() para executar o construtor da superclasse.

Após o uso de super, os atributos da classe Carro são inicializados no trecho:

this.qtdPassageiros = qtdPassageiros;

this.capacidadeBagagem = capacidadeBagagem;

E como ficará a classe Caminhao que é subclasse de Veiculo? Vejamos:

public class Caminhao extends Veiculo {

private long cargaMaxima;

private int numeroEixos;

public Caminhao(String placa, String modelo, int anoFabricacao,

int kilometragem, int cargaMaxima, int numeroEixos)

super(placa, modelo, anoFabricacao, kilometragem);

this.cargaMaxima = cargaMaxima;

this.numeroEixos = numeroEixos;

} //fim construtor de Caminhao

} //fim classe Caminhao

104
Classes e objetos: uma visão mais aprofundada • CAPÍTULO 4

Após o uso de super, os atributos da classe Caminhao são inicializados no trecho:

this.cargaMaxima = cargaMaxima;

this.numeroEixos = numeroEixos;

Imagine um projeto de nome TestaVeiculo com as classes:

» TestaVeiculo (com a main),

» Veiculo (superclasse ou classe mãe),

» Carro (subclasse ou classe filha de Veiculo) e

» Caminhao (subclasse ou classe filha de Veiculo)

Para testar, podemos criar, por exemplo, dois objetos: ca e cm. Veja!

Carro ca = new Carro(“KNX-3428”, “Ford Focus”, 2015, 8560, 5, 350);

Caminhao cm = new Caminhao(“JRT-4983”, “VW Delivery”, 2012,

126385, 10000, 2);

Figura 40. Visualizando o exemplo anterior.

ca
cm
placa = "KNX-3428"
modelo = "Ford Focus"
anoFabricacao = 2015
placa = "JRT-4983"
quilometragem = 8560
modelo = "VW Delivery"
qtdPasssageiros = 5
anoFabricacao = 2012
capacidadeBagagem = 350
quilometragem = 126385
cargaMaxima = 10000
numeroEixos = 2

Fonte: elaborada pela autora.

Importante

Como é possível perceber, herança permite um grande reaproveitamento de código.

Ao se falar de herança, é preciso aprender o que é polimorfismo. O polimorfismo pode ser


compreendido como:

105
CAPÍTULO 4 • Classes e objetos: uma visão mais aprofundada

Um mesmo comportamento (método) pode se apresentar

de forma diferente em classes diferentes.

Figura 41. De onde vem polimorfismo?

Poli = vários
Morfismo = forma

Fonte adaptada: https://pixabay.com/pt/vectors/l%c3%a2mpada-el%c3%a9trica-id%c3%a9ia-


ilumina%c3%a7%c3%a3o-1926533/.

Dentro do contexto de herança, sabemos que quando definimos uma subclasse, ela herdará
os métodos da superclasse. Entretanto, a subclasse pode redefinir um método herdado, ou
seja, implementar o método herdado de outra forma.

Polimorfismo é um mecanismo no qual um método da superclasse é sobrescrito na


subclasse. Dessa forma, podemos ter o mesmo método implementado de duas ou mais
formas diferentes. O Java vai decidir qual método será chamado no momento da execução do
programa (ligação tardia ou late binding).

Importante

A palavra reservada super permite chamar o método da classe mãe que está sendo reescrito na classe filha (sobrescrita ou
overriding).

Exemplo: Considere as classes Veiculo e Carro já vistas. É possível escrevermos um


método imprimirDados na classe Veiculo e outro método imprimirDados na classe Carro,
caracterizando sobrescrita (overriding).

public class Veiculo {

protected String placa;

protected String modelo;

protected int anoFabricacao;

protected int kilometragem;

public Veiculo(String placa, String modelo,

int anoFabricacao, int kilometragem)

106
Classes e objetos: uma visão mais aprofundada • CAPÍTULO 4

this.placa = placa;

this.modelo = modelo;

this.anoFabricacao = anoFabricacao;

this.kilometragem = kilometragem;

} //fim do construtor

public void imprimirDados() {

System.out.println(“Placa = “ + placa + “ Modelo = “ + modelo

+ “ Ano de fabricação = “ + anoFabricacao

+ “ Kilometragem= “ + kilometragem);

} //fim imprimirDados

} //fim da classe Veiculo

O método imprimirDados na classe filha Carro pode ser escrito da seguinte forma:

public void imprimirDados() {

System.out.println(“ Placa = “ + placa + “ Modelo = “ + modelo

+ “ Ano de fabricação = “ + anoFabricacao

+ “ Kilometragem= “ + kilometragem

+ “ Quantidade de passageiros = “ + qtdPassageiros

+ “ Capacidade de Bagagem = “ + capacidadeBagagem);

Observe que os atributos da classe mãe Veiculo estão sendo acessados sem getters, pois os
atributos de Veiculo são protected.

É possível, no entanto, escrever uma versão bem melhor do método imprimirDados da


classe filha Carro, se usarmos super! Veja a seguir a versão mais atualizada da classe Carro:

107
CAPÍTULO 4 • Classes e objetos: uma visão mais aprofundada

public class Carro extends Veiculo {

private int qtdPassageiros;

private int capacidadeBagagem;

public Carro(String placa, String modelo, int anoFabricacao,

int kilometragem, int qtdPassageiros, int capacidadeBagagem)

super(placa, modelo, anoFabricacao, kilometragem);

this.qtdPassageiros = qtdPassageiros;

this.capacidadeBagagem = capacidadeBagagem;

} //fim construtor

public void imprimirDados() {

//chama o método imprimirDados da superclasse Veiculo

super.imprimirDados();

//imprime os dados específicos de carro

System.out.println(“ Quantidade de passageiros = “ + qtdPassageiros

+ “ Capacidade de Bagagem = “

+ capacidadeBagagem);

} //fim imprimirDados

} //fim classe Carro

108
Classes e objetos: uma visão mais aprofundada • CAPÍTULO 4

Exemplo:

Método original
public class Animal {

public void emiteSom() { System.out.println("???"); }

} //fim da classe Animal

public class Gato extends Animal {


Método emiteSom() é sobrescrito.
} Note que a assinatura do método
continua a mesma.
public class Cachorro extends Animal {

public void emiteSom() { System.out.println("latido"); }

} //fim da classe Cachorro

Vamos testar? Para isso, considere que foi criado o projeto Teste com as classes Teste
(com a main), Animal, Gato e Cachorro.

public class Teste {


public static void main(String[] args) {
Saída do programa:
Animal a1 = new Animal();
Gato a2 = new Gato(); ???
Cachorro a3 = new Cachorro(); ???
latido
a1.emiteSom();
a2.emiteSom();
a3.emiteSom();

} //fim main
} //fim classe Teste

Exemplo: E se usarmos o exemplo anterior com uma nova versão da classe Gato conforme
indicado a seguir?

public class Gato extends Animal {

public void emiteSom() {

System.out.println(“miado”);

} //fim Gato

109
CAPÍTULO 4 • Classes e objetos: uma visão mais aprofundada

Neste caso, a saída será outra:

Figura 42. Qual é a saída do programa?

???
miado
latido

Fonte: elaborada pela autora.

Exemplo: Considere a seguinte versão da classe Teste, a última versão da classe Gato e a
versão da classe Cachorro já vista.

public class Teste {


public static void main(String[] args) {
Saída do programa:
Animal a1 = new Animal();
Animal a2 = new Gato(); ???
Animal a3 = new Cachorro(); miado
latido
a1.emiteSom();
a2.emiteSom();
a3.emiteSom();

} //fim main
} //fim classe Teste

Atenção

Apesar das variáveis a2 e a3 serem do tipo Animal, elas referenciam instâncias de Gato e Cachorro.

Assim, o Java decide qual método emiteSom() chamar baseado na instância que está sendo referenciada e não no tipo da
variável.

Exemplo: Considere as classes Animal, Gato (última versão) e Cachorro já vistas, mas uma
nova classe Teste como mostrado a seguir:

public class Teste {


public static void main(String[] args) {
Animal a;

a = new Animal();
a.emiteSom(); Saída do programa:

a = new Gato(); ???


a.emiteSom(); miado
latido
a = new Cachorro();
a.emiteSom();

} //fim main

} //fim Teste

110
Classes e objetos: uma visão mais aprofundada • CAPÍTULO 4

Exemplo: Ainda considerando as classes Animal, Gato (última versão) e Cachorro já vistas,
segue uma nova versão da classe Teste usando vetor.

public class Teste {


public static void main(String[] args) {
Animal [ ] v = new Animal[3];

v[0] = new Animal();


Note que o vetor é de Animal.
v[1] = new Gato();
v[2] = new Cachorro(); Entretanto, o vetor pode receber
instâncias das subclasses de
for (int i = 0; i < v.length; i++) Animal (Gato e Cachorro).
v[i].emiteSom();
}

} Note que v[i] primeiro referencia


uma instância de Animal, depois
uma instância de Gato e, por último,
uma instância de Cachorro.

Atenção

No momento da execução, o Java verifica o objeto referenciado por v[i] e decide qual método emiteSom() deve ser chamado.

Por isso, chama-se de ligação tardia.

Não confunda sobrecarga (overloading) com sobrescrita (overriding)!

Veja os exemplos na figura a seguir:

Figura 43. Exemplo de sobrecarga e sobrescrita.

public class Teste { public class Animal {


public void imprime() { public void emiteSom() {
System.out.println("*"); System.out.println("???");
} }
} //fim Animal
public void imprime(int n) {
for (int i = 1; i <= n; i++) public class Gato extends Animal {
System.out.println("*"); public void emiteSom() {
} System.out.println("miado");
}
} //fim Teste } //fim Gato

public class Cachorro extends Animal {


public void emiteSom() {
System.out.println("latido");
}
} //fim Cachorro

Fonte: elaborada pela autora.

111
CAPÍTULO 4 • Classes e objetos: uma visão mais aprofundada

Importante

Existem diferenças fundamentais entre os conceitos OO de sobrecarga e sobrescrita como mostra o quadro a seguir:

Quadro 5. Sobrecarga x Sobrescrita.

Característica Sobrecarga Sobrescrita


Termo em inglês Overload. Override.
Local Métodos da mesma classe. Métodos em classes diferentes em uma
hierarquia de classes.
Assinatura Métodos com assinaturas diferentes. Métodos com a mesma assinatura.
Chamada do método Em tempo de compilação ou ligação Em tempo de execução ou ligação tardia
precoce (early binding). (late binding).

Fonte: elaborado pela autora.

Exemplo: Uma outra maneira de programar a main da classe Teste é usando o comando
for-each e o operador instanceof.

public class Teste {


public static void main(String[] args) {
Animal [ ] v = new Animal[3]; Saída:
v[0] = new Animal() ???
v[1] = new Gato(); Eu sou um gato
v[2] = new Cachorro(); miado
Eu sou um cachorro
for (Animal a : v)
latido
{
if (a instanceof Gato)
System.out.println("Eu sou um gato");
else if (a instanceof Cachorro)
System.out.println("Eu sou um cachorro");
a.emiteSom();
}
}
}

Atenção

A linha for (Animal a : v)

indica que “para cada a da classe Animal em v faça” ou

“para cada Animal a em v faça”

Veja que o vetor foi percorrido sem uso de índice.

Para verificarmos a instância referenciada por uma variável, em tempo de execução, usamos
o operador instanceof.

112
Classes e objetos: uma visão mais aprofundada • CAPÍTULO 4

Traduzindo: instância de

Vejamos o que acontece em cada if:

1º. if : se a é instância de Gato

2º. if : se a é instância de Cachorro

Sintaxe: <variável> instanceof <nome da classe>

4.4 Classe Abstrata

Considerando as classes Veiculo, Carro e Caminhao já estudadas, vimos que:

» Carro é um tipo de veículo.

» Caminhão é um tipo de veículo.

» Veículo tem placa, modelo e ano de fabricação

Agora, imagine uma concessionária e procure responder às seguintes perguntas:

» Se algum cliente entrar na concessionária e pedir para comprar um veículo, o


vendedor saberá o que deve vender?

» Se a concessionária anunciar que está vendendo um veículo, o cliente tem condições


de saber exatamente o que está comprando?

Isso ocorre porque Veiculo é uma abstração para Carro e Caminhao.

Classes Abstratas são classes que representam abstrações (conceitos) e não objetos
concretos do mundo que estamos representando. Elas são usadas como moldes para a
criação de outras classes e podem conter atributos e métodos.

No exemplo da concessionária, Veiculo é uma classe abstrata. Note que Veiculo define um
molde a partir do qual as classes concretas Carro e Caminhao são definidas.

Vejamos outros exemplos nas figuras a seguir:

Figura 44. Classe Abstrata Poligono.

Poligono

Triangulo Retangulo Pentagono

Fonte: elaborada pela autora.

113
CAPÍTULO 4 • Classes e objetos: uma visão mais aprofundada

Figura 45. Classes abstratas em laranja e classes concretas em amarelo.

Animal

Vertebrado Invertebrado

Mamifero Oviparo

Gato Cachorro Galinha Pombo

Fonte: elaborada pela autora.

E como indicar, durante a programação, que uma classe é abstrata? Usando a palavra
reservada abstract.

Importante

Classes abstratas são definidas em Java com o uso da palavra abstract na sua definição.

Exemplo: Considere a classe abstrata Veiculo

public abstract class Veiculo {

protected String modelo;

protected int anoFabricacao;

public Veiculo(String modelo, int anoFabricacao) {

this.modelo = modelo;

this.anoFabricacao = anoFabricacao;

} //fim construtor Veiculo

} //fim classe Veiculo

114
Classes e objetos: uma visão mais aprofundada • CAPÍTULO 4

Importante

Por não representarem elementos concretos, não é possível criar objetos a partir de classes abstratas. Ou seja, não é possível
instanciar uma classe abstrata.

Exemplo: Se na main, em uma classe de teste, fizermos:

Veiculo v = new Veiculo(“gol”, 2011);

ocorrerá erro de compilação.

Atenção

Quando definimos uma classe abstrata, muitas vezes nos deparamos com métodos que fazem sentido para aquela classe,
mas não temos como implementá-lo, porque a classe abstrata representa apenas uma abstração.

Exemplo:

public abstract class Poligono {


O cálculo da área de um
public double area() { polígono faz sentido, mas
??????? como implementar esse
} cálculo aqui?
}

Então, neste caso, o método area é um método abstrato.

A versão atualizada da classe abstrata Poligono é a seguinte:

public abstract class Poligono {

public abstract double area();

} Métodos abstratos não


têm implementação!

Importante

As classes concretas que herdam da classe abstrata devem, obrigatoriamente, implementar os métodos abstratos.

Exemplo: Imagine um projeto Java com a classe abstrata Poligono (última versão do
exemplo anterior) e a classe Retangulo a seguir:

115
CAPÍTULO 4 • Classes e objetos: uma visão mais aprofundada

public class Retangulo extends Poligono {


private double base, altura;

public Retangulo (double base, double altura) {

this.base = base;
this.altura = altura;

} //fim do construtor Retangulo

public double area() { return base * altura; }

} //fim da classe Retangulo


As classes concretas que
herdam de Poligono devem
implementar o método area

4.5 Interface

Imagine que analisamos o domínio de um problema e chegamos a três hierarquias mostradas


nas figuras a seguir:

Figura 46. Classe mãe Cliente e classes filhas ClientePF e ClientePJ.

Cliente

ClientePF ClientePJ

Fonte: elaborada pela autora.

Figura 47. Classe mãe Funcionario e filhas Diretor, Secretaria e Vendedor.

Funcionario

Diretor Secretaria Vendedor

Fonte: elaborada pela autora.

116
Classes e objetos: uma visão mais aprofundada • CAPÍTULO 4

Figura 48. Classe mãe Fornecedor.

Fornecedor

Fornecedor Fornecedor
Internacional Nacional

Fonte: elaborada pela autora.

Note que, Cliente, Funcionario e Fornecedor precisam acessar o sistema usando um login
e uma senha. Por esta razão, é preciso implementar um método para verificar se, dado um
login e uma senha, esse usuário tem acesso ao sistema.

Além disso, considere que o algoritmo de autenticação do cliente é diferente do algoritmo de


autenticação do funcionário, que, por sua vez, é diferente do algoritmo de autenticação do
fornecedor.

Neste caso específico, o que se quer é que as classes Cliente, Funcionario e Fornecedor
implementem o método:

boolean autenticar(String login, String senha)

Apesar de serem classes distintas, espera-se que todas as três classes sigam esse padrão
para autenticar os usuários, recebendo o login e a senha. Por esta razão, vamos definir uma
interface que todas essas classes devem implementar.

O método autenticar será implementado de forma diferente em cada caso, mas terá a mesma
assinatura.

Atenção

Não confunda interface com interface gráfica. Interface gráfica lida com botão, caixas de texto etc.

A definição de interface é parecida com a de uma classe, mas note que ela não implementa
os métodos! Observe a interface Autenticavel a seguir:

public interface Autenticavel {

public boolean autenticar(String login, String senha);

117
CAPÍTULO 4 • Classes e objetos: uma visão mais aprofundada

Repare que a interface só expõe o que o objeto deve fazer, e não como ele faz. Como ele faz
vai ser definido em uma implementação dessa interface, em cada classe que implementar
esta interface.

Assim como as classes, uma interface deve estar em um arquivo próprio, com o mesmo
nome da interface.

Exemplo: Considerando as classes Cliente e Funcionario das figuras anteriores, temos:

public class Cliente implements Autenticavel {

//considere código aqui

public class Funcionario implements Autenticavel {

//considere código aqui

Atenção

Uma classe define que vai implementar

uma interface através da palavra implements.

Uma classe pode implementar várias interfaces. É só separar os nomes das interfaces por
vírgula. Exemplo:

public class Funcionario implements Autenticavel, Ordenacao {

//considere código aqui

Atenção

É permitido que uma mesma classe use o extends e o implements ao mesmo tempo.

Ao implementar uma interface, a classe é obrigada a definir e, de preferência, implementar


todos os métodos definidos na interface, o que é semelhante ao conceito de método abstrato.

public class Cliente implements Autenticavel {

118
Classes e objetos: uma visão mais aprofundada • CAPÍTULO 4

public boolean autenticar(String login, String senha) {

// aqui escreve o código que implementa o método

// para o cliente

public class Funcionario implements Autenticavel {

public boolean autenticar(String login, String senha) {

// aqui escreve o código que implementa o método

// para o funcionário

Atenção

Interfaces não são classes.

Então, não é possível criar objetos usando interfaces.

Interfaces definem comportamentos que devem ser implementados.

Exemplo:

Autenticavel a;
Erro de compilação.
a = new Autenticavel();

Entretanto, é possível ter variáveis do tipo da interface referenciando objetos.

Exemplo:

Autenticavel a;

a = new Cliente();

a.autenticar(“joao”, “123”);

119
CAPÍTULO 4 • Classes e objetos: uma visão mais aprofundada

Veja a figura 49 para saber o que pode e o que não pode ao definir uma interface.

Figura 49. Regras para definição de interfaces.

Interfaces não podem ter construtores.

Interfaces só podem ter membros públicos. Logo, private e


protected não são permitidos.

Interfaces não podem implementar métodos, somente


defini-los.

Interfaces não podem ter atributos, somente constantes


estáticas.

Uma interface pode estender outra interface (use extends)


para criar uma hierarquia de interfaces.

Fonte: elaborada pela autora.

Atenção

As constantes definidas em uma interface são herdadas pelas classes que implementam essa interface. Entretanto, como elas
são públicas, podem ser usadas em qualquer lugar.

Para facilitar o seu aprendizado...

» Projeto TestaProfessor com as classes TestaProfessor (com a main) e Professor.

» Objetivo: Trabalhar com vetor de objetos.

» Observação: A classe Professor a seguir é praticamente a que foi estudada no vídeo da


Aula 3.

public class Professor {

//atributos privados

private int matricula;

private double salario;

120
Classes e objetos: uma visão mais aprofundada • CAPÍTULO 4

private String nome;

private String titulacao;

//construtor

public Professor(int matricula, double salario, String nome, String titulacao) {

this.matricula = matricula;

this.salario = salario;

this.nome = nome;

this.titulacao = titulacao;

//métodos

public void setMatricula(int matricula) { this.matricula = matricula; }

public void setSalario(double salario) { this.salario = salario; }

public void setNome(String nome) { this.nome = nome; }

public void setTitulacao(String titulo) { this.titulacao = titulo; }

public int getMatricula() { return matricula; }

public double getSalario() { return this.salario; }

121
CAPÍTULO 4 • Classes e objetos: uma visão mais aprofundada

public String getNome() { return nome; }

public String getTitulacao() { return titulacao; }

public void imprimir() {

System.out.print(“\n” + titulacao.toUpperCase() + “ “ + nome

+ “ de matricula “ + matricula);

System.out.printf(“ recebe R$ %.2f de salario mensal\n”, salario);

} //fim imprimir

} //fim da classe Professor

import java.util.Scanner;

public class TestaProfessor {

public static void main(String[] args) {

int mat;

float salario;

String nome, titulo;

Scanner teclado = new Scanner(System.in);

Professor v[ ] = new Professor[3];

System.out.println(“\n\nEntrada de dados dos professores”);

122
Classes e objetos: uma visão mais aprofundada • CAPÍTULO 4

for(int i = 0; i < v.length; i++) {

System.out.print(“Matricula: “);

mat = teclado.nextInt();

teclado.nextLine(); //Atenção! Ver comentário adiante!

System.out.print(“Nome: “);

nome = teclado.nextLine();

System.out.print(“Titulacao: “);

titulo = teclado.nextLine();

System.out.print(“Salario: “);

salario = teclado.nextFloat();

v[i] = new Professor(mat,salario,nome,titulo);

System.out.println(“\nSaida de dados dos professores\n”);

for(int i = 0; i < v.length; i++) {

System.out.println(“Professor(a) “ + v[i].getTitulacao() +

“ “ + v[i].getNome() + “ de matricula “ +

v[i].getMatricula() + “ recebe “ +

v[i].getSalario() + “ por mes.\n”);

}// fim do for

} //fim main

} //fim classe TestaProfessor

Atenção

A linha teclado.nextLine(); foi necessária para, durante a execução, ler o enter acionado logo após a entrada da matrícula.

Caso isso não fosse feito, não seria possível digitar com o nome.

123
CAPÍTULO 4 • Classes e objetos: uma visão mais aprofundada

Sintetizando

Síntese do capítulo:

» Vetor ou array é um agregado de dados homogêneos, ou seja, dados do mesmo tipo, dispostos de forma contígua na
memória.

» Cada componente do vetor é acessado via índice.

» Os índices de um vetor em Java variam de zero em diante.

» Em Java, vetores são objetos. Por isso, usa-se o new para criá-los.

» Os vetores em Java podem ser de tipos primitivos (int, float, double ...) ou de objetos.

» Um ou vários objetos de uma classe podem estar relacionados com um ou vários objetos de outra classe.

» Herança é o mecanismo pelo qual classes herdam atributos e métodos por meio de um relacionamento hierárquico,
garantindo reaproveitamento de código.

» Em herança existem as classes genéricas (superclasses ou classes mães) e as classes específicas (subclasses ou classes
filhas).

» Herança pode ser simples ou múltipla. No entanto, Java não tem herança múltipla.

» Para definir a herança entre duas classes devemos usar a palavra reservada extends na definição da subclasse.

» A palavra reservada super permite chamar o construtor da classe mãe dentro do construtor da classe filha, possibilitando
reaproveitamento de código.

» A palavra reservada super permite também chamar o método da classe mãe que está sendo reescrito na classe filha,
possibilitando reaproveitamento de código.

» Polimorfismo pode ser compreendido como um mesmo comportamento (método) pode se apresentar de forma diferente
em classes diferentes.

» Polimorfismo é um mecanismo no qual um método da superclasse é sobrescrito na subclasse.

» Sobrecarga e sobrescrita são conceitos distintos.

» Classes abstratas são usadas como moldes para a criação de outras classes e podem conter atributos e métodos.

» Classes abstratas não podem ser instanciadas.

» Usa-se a palavra reservada abstract para definir uma classe abstrata.

» Interfaces só expõem o que o objeto deve fazer, e não como ele faz.

» Interfaces não são classes. Portanto, não podem ser instanciadas.

» Uma classe define que vai implementar uma interface por meio da palavra implements.

» É possível uma classe herdar de uma classe mãe e implementar uma ou mais interfaces.

124
TRATAMENTO DE EXCEÇÕES
CAPÍTULO
5
Introdução do capítulo

Neste capítulo estaremos diante de vários tipos de erros. Dentre eles, erros que podem
ocorrer durante a execução do programa e que, normalmente, fogem do nosso controle.

Imagine um programa que irá ler a sua idade, mas você sem querer, digita o seu nome. O que
ocorrerá? Uma exceção.

Objetivos do capítulo

» Conceituar exceção.

» Apresentar as principais classes de exceções.

» Tratar exceções.

5.1 Conceitos

Como tratar, em Java, por exemplo, as seguintes situações?

» Divisão por zero.

» Erro na conversão de tipos. Por exemplo, converter uma string que só contém letras
em um número inteiro.

Todas essas situações em Java são chamadas de exceções e existe um mecanismo específico
para tratá-las chamado de tratamento de exceções.

As exceções em Java estão organizadas em uma hierarquia de classes, como ilustrado pela
figura a seguir.

125
CAPÍTULO 5 • Tratamento de exceções

Figura 50. Hierarquia de exceções.

Fonte: elaborada pela autora.

A partir da figura anterior vemos que, no topo da hierarquia, está a classe Throwable e
depois surgem dois grandes ramos de classes de exceção: o da classe Error e o da classe
Exception.

Um Error ocorre devido a problemas no sistema operacional (SO), na JVM ou no


hardware. Nesse caso, o melhor a fazer é deixar a JVM encerrar o programa.

O nosso interesse está na classe Exception. Essa é a classe mãe de todas as exceções que
nossos programas podem tratar. Ela está subdividida em dois ramos:

» RuntimeException:

› Pode ocorrer devido a um erro de programação, como, por exemplo: divisão por
zero, índice inválido do vetor, acesso a objeto nulo etc.

› Também são chamadas de exceções não verificadas (unchecked).

» Demais exceções:

› Ocorrem devido a um erro no programa causado por fatores externos, como, por
exemplo: erro na abertura de um arquivo, erro na impressão etc.

› Também são chamadas de exceções verificadas (checked).

Exemplo: Considere as classes públicas DividePorZero e TesteExcecao, cada uma em um


arquivo .java. Quando executamos o programa a seguir, observamos uma mensagem de
erro, visto que não é possível calcular divisão por zero.

1 public class DividePorZero {

126
Tratamento de exceções • CAPÍTULO 5

2 public void exec(){

3 System.out.println(3/0);

4 System.out.println(«imprime»);

5}

6}

1 public class TesteExcecao {

2 public static void main(String args[]) {

3 DividePorZero d = new DividePorZero();

4 d.exec();

5 }

6}

Como o programa não está tratando essa exceção (divisão por zero), o tratador padrão do
Java executa as seguintes tarefas:

» Imprime o nome da exceção e a mensagem de erro.

» Imprime a pilha de execução (sequência de chamadas dos métodos).

» Termina o programa.

Veja mais detalhadamente:

Figura 51. Entendendo uma exceção.

Esse é o nome da exceção


que ocorreu.

Exception in thread "main" java.lang.ArithmeticException: / by zero


at DividePorZero.exec(DividePorZero.java:3)
at TesteExcecao.main(TesteExcecao.java:4)

Essa é a pilha de execução, ou Essa é a descrição da


seja, a sequência de chamadas dos exceção, ou seja, a
métodos exec (da classe mensagem de erro.
DividePorZero) e main (da classe
TesteExcecao) .

Fonte: elaborada pela autora.

127
CAPÍTULO 5 • Tratamento de exceções

5.2 Implementando tratadores de exceção

O tratamento de exceções é um mecanismo que permite que o programa defina como as


situações inesperadas serão tratadas.

Existem três comandos relacionados ao tratamento de exceções:

» Blocos try...catch...finally

» Comando throws

» Comando throw

Veremos agora o bloco try ...catch...

Figura 52. Entendendo o try...catch...

Se ocorrer uma exceção no bloco


do try então a execução é
automaticamente desviada para o
bloco catch.
A variável é
referência a
exceção que
try { ocorreu. Com ela é
// Código que pode gerar uma possível acessar as
informações sobre
// exceção essa exceção.
} catch (Exception e) {
// Código que será executado quando ocorrer a exceção
}

No catch devemos definir a


exceção a ser tratada. Quando
definimos uma exceção estamos
tratando também todas as suas
subclasses.

Fonte: elaborada pela autora.

Saiba mais

try significa tentar;

catch significa capturar ou pegar.

128
Tratamento de exceções • CAPÍTULO 5

A classe Exception implementa alguns métodos que podemos executar em nossos


programas. Dentre eles está o método:

» getMessage() que retorna a mensagem de erro armazenada na exceção. Nem toda


exceção tem mensagem de erro (nesse caso o método retorna null).

Exemplo: Considere um trecho em Java que trata uma única exceção.

import java.util.Scanner;

public class TesteExcecaoEx {


public static void main(String args[]) {
int a, b, c;

Scanner t = new Scanner(System.in);


try {
System.out.print("Digite um valor inteiro: ");
a = t.nextInt();
System.out.print("Digite outro valor inteiro: ");
b = t.nextInt();
c = a / b;
System.out.printf("%d / %d = %d\n", a, b, c);

} catch(Exception e) {

System.out.printf("Erro: %s\n", e.getMessage());


}

} //fim main
Que exceções podem ocorrer?
} // fim classe
1. Usuário digitar um valor
inválido para a
2. Usuário digitar um valor
inválido para b
3. Usuário digitar ZERO para b

Vamos testar cada caso mencionado acima. Veja:

» Exceção 1: Foi digitado um valor não inteiro, como mostra a figura a seguir. Nesse
caso, a variável a não poderá receber a letra r e ocorrerá desvio na execução para o
bloco do catch a fim de capturar a exceção. Por fim, uma mensagem é impressa
usando getMessage e o objeto e.

Figura 53. Tela de saída para a entrada r.

Fonte: elaborada pela autora.

129
CAPÍTULO 5 • Tratamento de exceções

» Exceção 2: Foi digitado valor inteiro e depois um valor não inteiro. Nesse caso,
a variável a receberá o valor 45 e a variável b não poderá receber o valor real
indicado na figura. Nesse momento ocorrerá desvio na execução para o bloco do
catch a fim de capturar a exceção. Por fim, uma mensagem é impressa usando
getMessage e o objeto e.

Figura 54. Tela de saída para a entrada 45 e depois 5,6.

Fonte: elaborada pela autora.

» Exceção 3: Foram digitados dois valores inteiros, sendo que o segundo valor
digitado e que será atribuído à variável b é o valor 0. Neste caso, ocorrerá erro
na divisão por zero e a atribuição c = a / b não será executada. Nesse momento,
portanto, ocorrerá desvio na execução para o bloco do catch a fim de capturar a
exceção. Por fim, uma mensagem é impressa usando getMessage e o objeto e.

Figura 55. Tela de saída para a entrada 56 e 0.

Fonte: elaborada pela autora.

É possível tratar várias exceções associando vários catch’s ao mesmo try. Nesse caso, a ordem
dos tratadores é importante: eles devem estar ordenados das subclasses para a superclasse.

Exemplo: Considere um trecho de código em Java destacando os catchs.

Figura 56. Entendendo o try..catch com mais de uma exceção.

Primeiro o catch da exceção mais


específica. Se ocorrer um erro de
aritmética, esse código será executado.

try {
// Código a ser tratado
} catch (ArithmeticException e3) {
System.out.printf("Erro de aritmetica: %s\n",e3.getMessage());
} catch(IOException e2) {
System.out.printf("Erro de E/S: %s\n", e2.getMessage());
} catch(Exception e1) {
System.out.printf("Erro desconhecido: %s\n", e1.getMessage());
}

Por último o catch da exceção mais geral.


Para qualquer outro erro, esse código
será executado.

Se ocorrer um erro de E/S ou de qualquer de suas


subclasses, o código do 2º catch será executado.

Fonte: elaborada pela autora.

130
Tratamento de exceções • CAPÍTULO 5

O que acontece quando ocorre uma exceção?

Tabela 12. O que acontece quando ocorre uma exceção.

O método cria um objeto do tipo Exception e o envia para a JVM:


» Esse processo é chamado de “disparar uma exceção” (throw an exception).
» O objeto Exception criado contém todas as informações sobre o erro: seu tipo, o local onde
ocorreu, uma mensagem de descrição, a pilha de chamadas, etc.

A JVM procura um bloco try...catch para tratar a exceção no método que gerou a exceção. Se
encontrar, desvia a execução para o catch.

Se não encontrar, procura um bloco try...catch para tratar a exceção na pilha de execução,
ou seja, nos métodos que chamaram o método que gerou a exceção. Se encontrar, desvia a
execução para o primeiro catch que encontrar.

Se não encontrou nenhum tratador na pilha de execução, desvia para o tratador padrão da JVM
que interrompe a execução do programa.

Fonte: elaborada pela autora.

O bloco try ...catch pode contar, opcionalmente, com o trecho do finally (significa
finalmente). Veja:

Figura 57. Uso do finally.

try {
// Código a ser tratado
} catch (Exception e) {
System.out.println("Erro: %s\n”, e.getMessage());
}
finally {
// Esse código será sempre executado, independente
// se houve exceção ou não
}

finally não é obrigatório e não serve para capturar exceção.


Deve ser usado para instruções de "limpeza".

v
Fonte: elaborada pela autora.

131
CAPÍTULO 5 • Tratamento de exceções

5.3 Exceções verificadas e não verificadas

As exceções na linguagem Java são classificadas como:

» checked (verificadas): são exceções verificadas pelo compilador, como veremos mais
adiante.

» unchecked (não verificadas): não são verificadas pelo compilador, ocorrendo em


tempo de execução. Nesse caso, contamos com a captura das exceções usando o
comando try ...catch já visto. Vale observar que alguns casos podem ser evitados se
for feita uma programação correta.

Para as exceções checked (verificadas), o Java nos obriga a:

Figura 58. Exceções checadas.

Tratar as exceções no método onde ela pode ocorrer. Nesse


caso, implementamos o bloco try...catch visto anteriormente.

ou

Avisar que estamos cientes de que aquela exceção pode ocorrer,


mas não desejamos tratá-la.
Nesse caso, usamos o comando throws.

Fonte: elaborada pela autora.

Exemplo: Considere um trecho de programa que lê e imprime um arquivo texto. Esse


código pode gerar exceções checked do tipo FileNotFoundException ou IOException. A
questão aqui é que o programa não compila.

132
Tratamento de exceções • CAPÍTULO 5

public class ImprimeArquivo {


public static void main(String[] args) {

FileReader fr = new FileReader("arquivo.txt"); //abre o arquivo para leitura


BufferedReader f = new BufferedReader(fr);
String linha;

linha = f.readLine(); //lê uma linha do arquivo


while (linha != null) { //enquanto houver linha faça
System.out.println(linha); //imprime a linha na tela
linha = f.readLine(); //lê a próxima linha
}
f.close(); //fecha o arquivo
}
}

Para avisar ao compilador que não desejamos tratar esses erros, temos
que usar o comando throws. Assim, a compilação é realizada.
Veja a seguir como ficou o programa anterior com throws.

public classv ImprimeArquivo {


public static void main(String[] args) throws
FileNotFoundException, IOException
{

FileReader fr = new FileReader("arquivo.txt"); //abre o arquivo para leitura


BufferedReader f = new BufferedReader(fr);
String linha;

linha = f.readLine(); //lê uma linha do arquivo


while (linha != null) { //enquanto houver linha faça
System.out.println(linha); //imprime a linha na tela
linha = f.readLine(); //lê a próxima linha
}
f.close(); //fecha o arquivo
} //fim main
} //fim classe

Saiba mais

» FileNotFoundException significa “exceção de arquivo não encontrado”

» IOException significa “exceção de IO”

» IO significa Input – Output, ou seja, Entrada – Saída

» Para separar exceções com throws usa-se vírgula, como mostrado no exemplo anterior. Reveja aqui apenas uma linha do
exemplo:

public static void main(String[] args) throws FileNotFoundException, IOException

133
CAPÍTULO 5 • Tratamento de exceções

Após estudarmos os comandos try...catch (para capturar exceção) e throws (para declarar
que uma exceção pode ocorrer), veremos agora o comando throw.

A palavra throw em Inglês, quando traduzida, significa lançar. O objetivo no uso do throw
é que a exceção seja disparada ou lançada para outra parte do programa. Normalmente,
throw é usado para lançar uma exceção que nós mesmos criamos.

Atenção

Não confunda throws com throw. Enquanto throws declara que uma exceção pode ocorrer, throw lança uma exceção.

Exemplo: Se a base ou a altura forem menores ou iguais a zero, a execução do construtor


será interrompida e a exceção será disparada ou lançada.

public class Retangulo {

private int base, altura; //atributos

public Retangulo(int base, int altura) throws Exception {

if (base <= 0 || altura <= 0) {

Exception ex = new Exception(“Base e altura devem ser maiores que zero”);

throw ex; //lança a exceção ex

this.base = base;

this.altura = altura;

} //fim do construtor

} //fim da classe Retangulo

E para onde será lançada tal exceção criada no construtor da classe Retangulo? Irá para o
ponto onde o construtor foi chamado. Veja o próximo exemplo:

Exemplo: Capturando a exceção lançada no construtor da classe Retangulo.

134
Tratamento de exceções • CAPÍTULO 5

Importante

Para indicar o uso de parâmetros inválidos ou ilegais é possível usar a exceção IllegalArgumentException em vez de
Exception.

Nesse caso, não é necessário usar o comando throws.

Exemplo: Construtor da classe Retangulo lançando uma exceção da classe


IllegalArgumentException.

public Retangulo(double base, double altura) {

if (base <= 0 || altura <= 0) {

throw new IllegalArgumentException(“Erro: Base e/ou altura <= 0”);

this.base = base;

this.altura = altura;

} //fim do construtor da classe Retangulo

Outra forma de escrever o trecho do if é:

if (base <= 0 || altura <= 0) {

IllegalArgumentException ex = new IllegalArgumentException(“Erro...”);

throw ex;

135
CAPÍTULO 5 • Tratamento de exceções

Sintetizando

Síntese do capítulo:

» Erros de lógica de programação, tais como acesso a índice fora dos limites do vetor, divisão por zero, entre outros, são
exceções.

» Erros devido a condições do ambiente de execução, que estão fora do controle do programador, mas podem ser
contornados em tempo de execução, tais como, arquivo não encontrado, rede fora do ar, entre outros, são exceções.

» Erros graves onde não adianta tentarmos recuperação, pois fogem do controle do programador e não podem ser
contornados, tais como falta de memória, erro interno na JVM, são exemplos de exceção.

» Existe uma hierarquia de classes de exceção. Das exceções dessa hierarquia, usaremos a classe Exception e suas subclasses.

» Quando uma exceção ocorre, são informados o nome da exceção que ocorreu e seu pacote, uma pilha de execução com a
sequência de chamadas dos métodos e a descrição da exceção, que contém a mensagem de erro.

» O tratamento de exceções é um mecanismo que permite que o programa defina como as situações inesperadas serão
tratadas.

» Comandos para tratamentos de exceções: try ...catch (com ou sem finally), throws e throw.

» O comando try...catch (com ou sem finally) irá executar o trecho e, caso a exceção ocorra, irá capturar a exceção no bloco
do catch.

» O finally não captura exceção.

» É possível ter mais de um catch para um bloco try.

» As exceções podem ser verificadas (checked) ou não verificadas (unchecked).

» O comando throws é usado para declararmos que uma exceção pode ocorrer.

» O comando throw serve para lançar uma exceção para outro trecho do programa poder tratá-la.

136
CAPÍTULO
COLEÇÕES DE OBJETOS 6
Introdução do capítulo

A linguagem Java tem um conjunto de classes que servem para armazenar, na memória,
coleções de objetos.

Tais classes oferecem a vantagem de não termos que saber, de antemão, a quantidade de
elementos que iremos armazenar, o que é uma grande vantagem se compararmos com vetor.

Objetivos do capítulo

» Apresentar as principais interfaces e classes no estudo de coleções.

» Realizar um estudo teórico e prático da classe ArrayList.

» Identificar as classes Wrapper e seu papel na criação de listas de objetos.

6.1 Conceitos

As coleções em Java são divididas em três grandes grupos:

» Set: coleções de objetos que representam conjuntos de objetos.

» List: coleções de objetos que representam listas de objetos.

» Map: coleções de objetos que representam mapas ou dicionários.

Essas coleções em Java são definidas a partir de quatro interfaces principais:

» Collection: define métodos comuns a conjuntos e listas.

» Set: define métodos para manipulação de conjuntos de objetos.

» List: define métodos para manipulação de listas de objetos.

» Map: define métodos para manipulação de mapas ou dicionários.

137
CAPÍTULO 6 • Coleções de objetos

Figura 59. Hierarquias de interfaces.

Fonte: elaborada pela autora.

A figura 60 representa as principais classes que implementam as interfaces Collection,


Set, List, SortedSet, Map e SortedMap, além de mostrar também a classe Collections.

Figura 60. Principais interfaces (em azul) e classes.

Fonte: elaborada pela autora.

Atenção

Não confundir interface Collection com classe Collections.

Basicamente, temos que:

» Um Set nos remete a mesma ideia de conjuntos da matemática, ou seja, um conjunto


de objetos sem duplicidade de elementos. Assim, se tentarmos armazenar mais de
uma vez o mesmo objeto em um Set, não teremos objeto duplicado.

» Um List é uma lista de objetos com a possibilidade de duplicidade de elementos.


Assim, se tentarmos armazenar mais de uma vez o mesmo objeto em um List, ele
ficará duplicado na lista.

» Um Map é um objeto que mapeia chaves em valores. Um map não pode conter
chaves duplicadas, ou seja, cada chave pode ser mapeada em no máximo um valor.

138
Coleções de objetos • CAPÍTULO 6

Importante

Todas as coleções estão definidas no pacote java.util.

6.2 Classe ArrayList

ArrayList é uma classe concreta que implementa a interface List, ou seja, uma lista de objetos.
Cada objeto armazenado no ArrayList tem um índice e por meio desse índice, é possível
manipular o objeto da lista. Note que o índice inicial é zero.

Figura 61. Algumas interfaces e classes.

Fonte: elaborada pela autora.

Atenção

» A figura anterior mostra as interfaces List e Collection, além das classes LinkedList, ArrayList e Vector que implementam a
interface List.

» List é sub-interface de Collection.

A classe ArrayList conta com vários métodos importantes, como, por exemplo:

» void add(índice, Object): adiciona o objeto à coleção na posição do índice.

» boolean add(Object): adiciona o objeto sempre no final da lista.

» Object get(índice): recupera o objeto de determinada posição da lista usando o


índice.

» Object remove(índice): remove o objeto de determinada posição da lista e retorna o


objeto removido.

» boolean remove(Object): remove o objeto da lista e move os objetos subsequentes


para novas posições, ajustando a lista.

» int size(): retorna a quantidade de objetos presentes na lista.

139
CAPÍTULO 6 • Coleções de objetos

Importante

Um objeto da classe ArrayList é uma lista redimensionável.

Exemplo: Criando uma lista com nomes e usando os métodos add e remove. Note que lista é
um objeto da classe ArrayList.

import java.util.ArrayList;

public class ExemploArrayList {


Cria uma lista vazia.
public static void main(String[] args) {

ArrayList lista = new ArrayList();

lista.add("Dinardo");
Insere no fim da lista.
lista.add("Rosa");

lista.add("Dinardo");

lista.add("Rafael");
lista.add(2, "Carlos"); Insere em uma posição específica.

lista.add("Luís");

lista.remove("Carlos");
Remove o objeto.
lista.remove("Rafael");

lista.remove("Dinardo");

lista.remove(2);
} Remove o objeto dessa posição.
}

Observe o passo a passo do programa anterior:

Etapa 1: Após adicionar Dinardo, Rosa, Dinardo e Rafael

Dinardo → Rosa → Dinardo → Rafael

Etapa 2: Após adicionar Carlos na posição de índice 2

Dinardo → Rosa → Carlos → Dinardo → Rafael

Etapa 3: Após adicionar Luís

Dinardo → Rosa → Carlos → Dinardo → Rafael → Luís

140
Coleções de objetos • CAPÍTULO 6

Etapa 4: Removendo Carlos, Rafael e Dinardo

Rosa → Dinardo → Luís

Note que a primeira ocorrência de Dinardo foi removida.

Etapa 5: Removendo o elemento da posição de índice 2.

Rosa → Dinardo

Exemplo: Criando uma lista de objetos de tipos diferentes.

import java.util.ArrayList;
public class ExemploArrayList {

public static void main(String[] args) {

ArrayList lista = new ArrayList();

lista.add("Dinardo");
lista.add("Rosa");
lista.add(10); Definido dessa forma, o ArrayList
lista.add(2465); armazena objetos do tipo Object.
lista.add(3.14159);
lista.add('A');
}
}

Exemplo: Podemos recuperar um elemento da lista pelo seu índice. Para isso, basta usar o
método get.

import java.util.ArrayList;

public class ExemploArrayList {

public static void main(String[] args) {

ArrayList lista = new ArrayList();

lista.add("Dinardo");
lista.add("Rosa");
lista.add(10);
lista.add(2465);
lista.add(3.14159);
lista.add('A');

System.out.println(lista.get(0));
System.out.println(lista.get(3));
System.out.println(lista.get(4));
System.out.println(lista.get(5));
}
}

O método get(i) recupera o elemento da


posição de índice i.
O índice inicial é ZERO, como no vetor.

141
CAPÍTULO 6 • Coleções de objetos

Após adicionar com add os elementos à lista, temos:

Dinardo → Rosa → 10 → 2465 → 3.14159 → A

Depois, cada elemento da lista é acessado pelo índice usando o método get. Assim, por
exemplo, lista.get(0) obtém o 1º elemento do objeto lista e com o System.out.println,
ocorre a impressão na tela.

Figura 62. Saída do programa anterior.

Dinardo
2465
3.14159
A

Fonte adaptada: https://www.shutterstock.com/pt/image-photo/biophilia-workspace-home-office-room-


computer-1899736342.

Exemplo: Observe a melhoria na hora de percorrer a lista e imprimir seus dados. Para isso, foi
usado o método size.

import java.util.ArrayList;

public class TesteArrayList {

public static void main(String[] args) {

ArrayList lista = new ArrayList();

lista.add("Dinardo");
Saída do programa:
lista.add("Rosa");
Dinardo
lista.add(10);
Rosa
lista.add(2465);
10
lista.add(3.14159);
2465
lista.add('A');
3.14159
A

for (int i= 0; i< lista.size(); i++)


System.out.println(lista.get(i));
}
}

142
Coleções de objetos • CAPÍTULO 6

No exemplo anterior, vimos que podemos percorrer um ArrayList com for. Note que também
é possível percorrer com for...each. Nesse caso, não usamos índice.

Como ficaria o trecho do for, do exemplo anterior, reescrito com for...each?

Veja:

for (Object obj : lista)

System.out.println(obj);

Podemos entender da seguinte forma:

para cada obj em lista imprima obj

6.3 Classes Wrapper

Em Java, os tipos básicos int, long, byte, short, float, double, char e boolean não são objetos.
Entretanto, a maioria das classes da biblioteca Java, como as classes que implementam as
coleções, por exemplo, trabalha somente com objetos.

Para resolver esse problema foram definidas classes wrapper, ou seja, classes que encapsulam
ou “embrulham” os tipos básicos para que estes possam ser tratados como objetos.

Tabela 13. Classes wrapper.

Classe wrapper Tipo armazenado na classe


Integer int
Long long
Byte byte
Short short
Float float
Double double
Character char
Boolean boolean

Fonte: elaborada pela autora.

Na maior parte das vezes, o Java converte o tipo básico em uma classe wrapper (boxing) ou
uma classe wrapper em um tipo básico (unboxing) de forma automática.

Exemplo:

int x = 10;

Integer a = 10;

143
CAPÍTULO 6 • Coleções de objetos

Integer b = x + 1;

int y = a;

a = a + 1;

b++;

A partir daí e do último exemplo da seção anterior, vemos que, quando é adicionado um
valor qualquer, por exemplo, o inteiro 2465 à lista

lista.add(2465);

O valor 2465 é “embrulhado” com a classe wrapper adequada e é adicionado com o método
add à lista criada com ArrayList. Ou seja, tínhamos um valor inteiro para ser adicionado ou
inserido em uma lista de objetos e, com a classe wrapper, passamos a ter um objeto com o
valor inteiro para que a inserção na lista ocorresse.

Para adicionar o valor inteiro 2465 foi usada a classe wrapper Integer. E para os valores 3.14159
e ‘A’ do mesmo exemplo? Foram usadas, respectivamente, as classes Double e Character.

Sintetizando

Síntese do capítulo:

» As coleções em Java são divididas em três grandes grupos: Set, List e Map.

» As coleções mencionadas são definidas a partir de quatro interfaces principais: Collection, Set, List e Map.

» A classe ArrayList implementa a interface List.

» A classe ArrayList permite criar listas redimensionáveis de objetos, cujos elementos podem ser acessados via índice.

» O índice inicial de uma lista é zero.

» As classes wrapper encapsulam os tipos básicos da linguagem.

» Classes wrapper: Integer, Long, Byte, Short, Float, Double, Character e Boolean.

» Na maior parte das vezes, o Java converte o tipo básico em uma classe wrapper (boxing) ou uma classe wrapper em um
tipo básico (unboxing) de forma automática.

144
Referências
DEITEL, Paul J.; DEITEL, Harvey M. Java: como programar. São Paulo: Pearson Education do Brasil, 2017. 10ª.
Edição.

ECKEL, Bruce. Java Platform Standard Edition Documentation. Disponível em: https://docs.oracle.com/
search/?q=Java%20plataform&pg=2&size=10&product=en%2Fjava&category=en%2Fjava&showfirstpage
=true&lang=en. Acesso em: 23 out. 2022.

ECKEL, Bruce. Thinking in Java. Prentice Hall, 5ª. Edição, 2022.

HORSTMANN, Cay S.; CORNELL, Gary. Core Java. Volume I – Fundamentos. São Paulo: Pearson Education do
Brasil, 2010.

Sites
https://www.shutterstock.com/pt/image-photo/kazan-russia-april-11-2017-set-645421069.

https://www.oracle.com/java/.

https://pixabay.com/pt/vectors/computador-port%c3%a1til-computador-2298286/.

www.eclipse.org.

https://www.shutterstock.com/pt/image-vector/business-man-character-has-take-difficult-357576257.

https://pixabay.com/pt/vectors/l%c3%a2mpada-el%c3%a9trica-id%c3%a9ia-ilumina%c3%a7%c3%a3o-1926533/.

https://pixabay.com/pt/vectors/casa-%c3%adcone-s%c3%admbolo-arquitetura-2492054/.

https://pixabay.com/pt/vectors/bmw-carro-roadster-carro-esporte-158703/.

https://www.shutterstock.com/pt/image-photo/happy-young-university-students-studying-books-522554425.

https://www.shutterstock.com/pt/image-photo/biophilia-workspace-home-office-room-computer-1899736342.

145

Você também pode gostar

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy