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

Java JSE Programação Básica

O documento é um guia introdutório sobre a programação básica em Java JSE, abordando desde a história da linguagem até conceitos fundamentais como classes, objetos, herança e polimorfismo. Ele também inclui instruções sobre o uso do IDE Eclipse e exercícios práticos para consolidar o aprendizado. O material é estruturado em módulos que facilitam a compreensão dos princípios da programação orientada a objetos e do desenvolvimento de software em Java.
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)
3 visualizações106 páginas

Java JSE Programação Básica

O documento é um guia introdutório sobre a programação básica em Java JSE, abordando desde a história da linguagem até conceitos fundamentais como classes, objetos, herança e polimorfismo. Ele também inclui instruções sobre o uso do IDE Eclipse e exercícios práticos para consolidar o aprendizado. O material é estruturado em módulos que facilitam a compreensão dos princípios da programação orientada a objetos e do desenvolvimento de software em Java.
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

Java JSE: Programação Básica

1
Java JSE: Programação Básica

Apresentação 4

Módulo 1: A Plataforma Java 5


Aula 1: Histórico e evolução da linguagem Java 5
História da linguagem de programação Java 5
Principais conceitos da plataforma Java 7
Aula 2: IDE Eclipse 8
Ambiente de desenvolvimento Java 8
Obtendo e instalando o Eclipse 9
Conhecendo o Eclipse 11
Sumário Criando o primeiro projeto no Eclipse 14
Exercício: dado virtual 24
Aula 3: estrutura básica de programação em Java SE 24
Instruções de entrada e saída em janelas 24
Tipos primitivos do Java, strings e conversão de valores 26
Conceitos básicos de memória, comparação de strings e strings mutáveis 28
Uso do operador ternário 30
Projeto calculadora 30
Exercícios do Módulo 1 32

Módulo 2 – Classes e objetos em Java 35


Aula 4 – Conceitos básicos de classes e objetos 35
Classes, objetos, métodos e instância 35
Implementando a classe no sistema bancário 38
Métodos construtores 42
Métodos estáticos 44
Exercício prático - complementando o sistema bancário 46
Aula 5 - Encapsulamento 47
Definição e exemplo de encapsulamento 47
Modificadores de visibilidade: private, public e protected 47
Usando getters e setters 48
Exercício adicional 52
Encapsulamento de campos na prática: exercício prático guiado 53
Exercício do Módulo 2 57

Módulo 3 – Herança e polimorfismo 59


Aula 6 – Herança em Java 59
Conceito de herança 59
Superclasses e subclasses 60
Exercício prático guiado: herança de cliente no sistema bancário 60
Aula 7 – Polimorfismo 67
Conceito de polimorfismo 67
Sobrecarga de métodos 69
Polimorfismo na prática em Java: exercício prático guiado 70
Exercício do Módulo 3 75

Módulo 4 – Arrays de objetos e coleções 76


Aula 8 - Arrays e coleções em Java 76
Arrays de objetos e coleções 76

2
Java JSE: Programação Básica

Uso de ArrayList e métodos para manipulação 77


Uso de coleções no sistema bancário: exercício prático guiado 79
Exercício do Módulo 4 83

Respostas Comentadas dos Exercícios 84


Módulo 1 84
Dado Virtual 84
Potência 85
Conversor Celsius para Fahrenheit 86
Histograma 89
Módulo 2 91
Forca 91
Módulo 3 95
Complementando o sistema bancário 95
Funcionarios 97
Módulo 4 101
Contatos 101

Considerações Finais 105

Referências Bibliográficas 106

3
Java JSE: Programação Básica

Apresentação

Caro aluno(a), seja bem-vindo(a) à nossa disciplina, na qual vamos trabalhar juntos nos conceitos e
práticas essenciais da linguagem Java.

Neste momento, você já deve possuir uma boa noção dos conceitos básicos de engenharia de software,
modelagem orientada a objetos, UML e lógica de programação. Todos esses temas são essenciais para
esta disciplina, pois a programação em Java permite que você coloque em prática os princípios básicos
de engenharia de software, implemente os sistemas orientados a objetos modelados com a UML e use os
algoritmos e estruturas básicas que fundamentam a lógica de programação.

Nossa disciplina trata da introdução formal ao mundo da linguagem da Java por meio da sua “fundação
básica”, o Java SE (Standard Edition). A linguagem Java, dada sua história e imensa popularidade, abrange
uma série de áreas de utilização. O Java SE concentra-se em abranger os elementos básicos dela, que são
comuns para todas as aplicações, sejam programas do tipo desktop, aplicativos web ou para dispositivos
móveis. Ou seja, é o básico da linguagem, que você utilizará em praticamente qualquer programa feito em
Java.

Quando você estiver mais avançado dentro da tecnologia Java, conhecerá os outros campos de aplicação
da linguagem, como nos softwares empresariais e destinados à web que são criados com o Java EE (Enterprise
Edition), mas perceberá que o Java SE estará sempre lá com você.

Nesta disciplina, começaremos a utilizar um IDE - integrated development environment, ou ambiente de


desenvolvimento integrado. Um IDE é um aplicativo que facilita bastante o desenvolvimento de software,
pois agrega recursos de edição, compilação, teste e depuração de um programa em um mesmo local,
aumentando a produtividade do desenvolvedor. Você utilizará, além do IDE, o compilador e interpretador
Java incluso no JDK.

Então vamos lá! Prepare-se para mergulhar de cabeça na linguagem de programação orientada a objetos
mais usada no mundo.

Prof. Luiz Carlos Querino Filho

4
Java JSE: Programação Básica

Módulo 1: A Plataforma Java

Este primeiro módulo trata de uma rápida introdução formal a Java, que pode ser definida não apenas
como uma linguagem de programação, mas também uma completa plataforma de desenvolvimento de sof-
tware. Veremos um pouco de sua história e seu modo de funcionamento e faremos a instalação do ambiente
de desenvolvimento integrado no qual criaremos nossos aplicativos.

Aula 1: Histórico e evolução da linguagem Java

História da linguagem de programação As vantagens da programação OO em relação à


Java estruturada são muitas: maior produtividade, aliada a
uma grande capacidade de reutilização. Assim, várias
Para entender o início da linguagem Java, temos linguagens foram desenvolvidas implementando esse
que compreender a distinção básica entre os para- paradigma. Dentre as que ganharam rápida popula-
digmas de programação orientado a objetos e estru- ridade e aceitação, nos primórdios, estão SmallTalk
turado. e C++. Esta última, principalmente por usar como
base a linguagem C, largamente conhecida pelos
No paradigma estruturado, que surgiu primeiro, programadores, tornou-se em pouco tempo a princi-
os programas são definidos como uma coleção de pal linguagem OO em uso. Porém tinha (e ainda tem)
funções e estruturas de programação básicas, que alguns pontos negativos, como uma sintaxe comple-
por sua vez utilizam dados armazenados em variá- xa para declaração e uso de classes e um modelo
veis. Não há uma relação óbvia e direta entre fun- de gerenciamento de memória manual, que obriga o
ções e dados; é responsabilidade do programador programador a ter controle preciso sobre a memória
estabelecê-la, passando as variáveis como parâme- alocada para objetos.
tros das funções.

Já no paradigma orientado a objetos, tem-se uma


relação mais direta entre dados e ações (as funções
da programação estruturada). Os dados possuem
funções, que atuam diretamente sobre eles (ou sobre
outros dados). Isso ocorre colocando-os em unidades
denominadas objetos, os quais passam a ter também
ações: passam a “saber” como usar ou processar
seus dados (ou os existentes em outros objetos).

Usando a orientação a objetos (OO), podemos


tornar os programas mais próximos do mundo real,
Fonte: [Link]
pois nosso dia a dia é uma constante interação entre
vector/[Link]
“objetos” que contêm informações.

5
Java JSE: Programação Básica

De acordo com Deitel e Deitel (2010), em junho À medida que se conhece a linguagem e seus re-
de 1991, James Gosling, Mike Sheridan e Patrick Nau- cursos, percebe-se que, duas décadas depois, esses
ghton, programadores da extinta Sun Microsystems princípios básicos foram plenamente alcançados e
(que foi adquirida pela Oracle em 2009), começaram implementados.
a desenvolver uma linguagem de programação OO
que fosse mais fácil de ser aprendida e utilizada do Em virtude de a Sun (e, hoje, a Oracle) sempre
que C++. Além disso, deveria possuir recursos avan- ter disponibilizado as ferramentas para criação de
çados de gerenciamento de memória que livrassem programas Java pela internet (o JDK), a linguagem
o programador da tarefa de alocar e liberar recursos ganhou enorme aceitação na comunidade de desen-
para os objetos e, sobretudo, poder ser executada volvedores, principalmente entre os entusiastas do
em computadores de diferentes arquiteturas. Como chamado software livre ou open source. Por essas e
eram ávidos consumidores de café, batizaram a lin- outras razões, em 2006, a Sun passou a liberar todo
guagem com o nome da ilha de onde vinha a sua o código-fonte principal dela, usando licenças livres
marca favorita da bebida: Java. como a GPL.

A linguagem Java foi lançada oficialmente em Hoje Java é, além de uma linguagem, uma pla-
1995 e, graças a seus recursos poderosos, sua sim- taforma completa de desenvolvimento e conta com
plicidade e a facilidade no entendimento de sua sin- uma rica comunidade de suporte. A filosofia do sof-
taxe, além da capacidade de execução em múltiplas tware livre está tão presente nela que, apesar de a
plataformas, tornou-se rapidamente um sucesso. Ou- marca ainda pertencer a uma empresa, todo o pro-
tra característica importante que contribuiu para o cesso de atualização, melhoria e evolução da lingua-
seu sucesso foi a existência de recursos para a sua gem é controlado por um grupo que envolve várias
utilização na internet. Na época, o acesso à rede co- pessoas da comunidade, conhecido como Java Com-
meçava a ser disponibilizado comercialmente, vindo munity Process (JCP). Até mesmo a mascote oficial
a alcançar milhões de pessoas e a se tornar parte da da linguagem, o Duke (figura 1), tem seu desenho
vida de todo o mundo. liberado nos termos do software livre e pode ser usa-
do sem restrições.
James Gosling, considerado o “pai do Java”, deli-
neou no documento The Java language environment
(que se tornou a “definição formal” da linguagem)
os cinco princípios básicos dela (GOSLING; MCGIL-
TON, 1997):

1. Java deve ser uma linguagem simples, orien-


tada a objeto e com conceitos familiares aos
programadores.
2. Java deve ser robusta e segura.
3. Java deve ser neutra em relação à arquitetu-
ra de execução, ou seja, deve ser portável.
4. Java deve executar com alto desempenho.
5. Java deve ser interpretada, utilizar threads e Figura 1: Duke, o mascote oficial da Java. Fonte: http://
ser dinâmica. [Link]/wiki/File:Duke_Wave.png.

6
Java JSE: Programação Básica

Principais conceitos da plataforma Java

Como dissemos, Java não é somente uma linguagem de programação, mas uma plataforma de desenvol-
vimento de software. Mas o que isso significa? Que, junto da linguagem, existem bibliotecas, ferramentas,
frameworks e recursos para que o programador crie aplicativos nos mais diferentes tipos de equipamentos,
de computadores desktop a servidores e de smartphones a set-top-boxes.

A plataforma Java (ou seja, a base em que os programas Java executam) foi criada desde o início com o
intuito de ser utilizada nos mais variados tipos de aparelhos, com os mais diversos tipos de processadores,
arquiteturas e sistemas operacionais.

Mas como isso é possível?

Se você já programava antes de realizar este curso, com certeza deve conhecer o processo de compilação,
em que o programa compilador converte o código-fonte escrito em uma determinada linguagem de progra-
mação para linguagem de máquina, que o computador consegue processar. Porém, com esse processo, o
programa passa a ficar preso a um tipo específico de computador, que entenda a linguagem de máquina
gerada.

Para conseguir sua meta de fazer um mesmo programa ser executado em diferentes plataformas, o Java
teve de seguir uma abordagem diferente.

Um programa Java (com código escrito em arquivos com a extensão .java) também passa por um proces-
so de compilação. Mas o arquivo gerado pelo compilador Java (o javac) não conterá código em linguagem de
máquina, pois este é sempre dependente da plataforma na qual o programa será executado. Ao invés disso,
é gerado em bytecode, que são instruções que somente podem ser executadas pelo Java Virtual Machine
(JVM), a máquina virtual Java. Esse processo é ilustrado na figura 2.

Figura 2: Ciclo de compilação e execução de um programa escrito em Java. Fonte: Adaptado de Oracle (2014).

Observe a sequência do processo de compilação e execução de um programa Java na figura 2. O com-


pilador javac analisa o código-fonte escrito no arquivo [Link] e gera o arquivo [Link], que
contém o bytecode do programa. Esse bytecode apenas poderá ser executado por um programa especial, a
máquina virtual Java, que deverá estar sempre presente no computador no qual queremos executar nosso
programa. É tarefa da JVM ler o bytecode e convertê-lo para a linguagem de máquina específica do compu-
tador e do sistema operacional no qual será executado.

O compilador javac faz parte do JDK. Mas e a máquina virtual?

7
Java JSE: Programação Básica

O JDK contém, além do javac e das bibliotecas básicas da linguagem, uma cópia da máquina virtual, que
também é instalada. Isso porque, sem a JVM, não seria possível executar os programas usando o comando
java, que é o interpretador de bytecode, responsável por enviar o programa para ser executado.

Quem não é programador não precisa, obviamente, instalar o JDK para obter a JVM. Por isso, a Oracle
disponibiliza também o Java Runtime Environment (JRE), que contém a máquina virtual para que os usuários
comuns possam executar os aplicativos escritos em Java no seu formato compilado, ou seja, em bytecode.

Isso leva à seguinte conclusão: a máquina virtual Java funciona como uma espécie de tradutor entre o
bytecode e a linguagem de máquina do computador no qual o programa será executado. Então, consequen-
temente, a máquina virtual deve ser feita “sob medida” para a plataforma (o tipo de computador e sistema
operacional) no qual o programa será executado.

Por essa razão, o computador (ou dispositivo) em que um programa escrito em Java será executado pos-
sui uma máquina virtual construída especificamente para ele. Isso significa que aquela usada em sistemas
Windows não funciona em sistemas Linux. Você deverá ter instalada a máquina virtual específica para seu
computador e sistema operacional.

Aula 2: IDE Eclipse

Ambiente de desenvolvimento Java

Como você viu na figura 2, o processo de compilação e execução de um programa em Java envolve o uso
de dois utilitários instalados pelo JDK no seu computador: o compilador javac e o interpretador java.

Contudo, à medida que os programas Java crescem em tamanho e complexidade, trabalhar com linha de
comando torna-se bastante improdutivo. Começa-se a gastar um tempo valioso no ciclo de desenvolvimento
do software. Para otimizar o processo de criação de um aplicativo, existem os IDEs (integrated development
environments, ou ambientes de desenvolvimento integrado). Esses programas integram um conjunto de re-
cursos que auxiliam o desenvolvedor no processo de criação de um software, como:

• Um editor de código, com colorização de sintaxe e possibilidade de autocompletar nomes de comandos


e identificadores.
• Um facilitador de acesso ao compilador, em que basta o usuário clicar em um botão para que o proces-
so de compilação seja feito para todos os arquivos de código-fonte existentes no programa.
• Execução automática do programa compilado com sucesso ou, no caso de erros de compilação, a visu-
alização destes e a localização dos pontos no código que necessitam de correção.
• Recursos de depuração visual, para que o programador possa executar o código linha por linha, anali-
sando os valores obtidos.
• Acesso à documentação da linguagem.

Dada a imensa popularidade da linguagem Java, existem diversos IDEs disponíveis para utilização, cada
uma com suas vantagens e desvantagens. Os mais populares entre os desenvolvedores são o Eclipse (livre e
mantido por uma comunidade mundial de usuários) e o NetBeans (também livre, mas mantido pela Oracle).

8
Java JSE: Programação Básica

Ambos possuem recursos avançados de edição, compilação e teste de aplicativos Java, podendo ser conside-
rados até mesmo equivalentes em quantidade de funcionalidades.

Nesta disciplina, utilizaremos o Eclipse por uma razão a mais: ele é o IDE “oficial” (por enquanto) para o
desenvolvimento de aplicativos Android. Por isso, conhecendo o Eclipse agora, você já começa também a se
preparar para a programação em Java para a plataforma de computação móvel mais usada no mundo.

IDE não é a mesma coisa que compilador!


Essa é uma confusão muito comum.
Não é o IDE que compila os programas. Na maioria dos casos (como no Eclipse), ele funciona como
um intermediário entre o usuário e o compilador/interpretador da linguagem. É responsável por passar
o código digitado pelo usuário ao compilador e repassar o resultado (como erros e avisos). Existem
casos em que um IDE traz junto um compilador, mas, em outros, é necessário que o usuário já o tenha
instalado previamente.

Obtendo e instalando o Eclipse

O Eclipse é um software livre, com código-fonte aberto. Isso significa, entre outras coisas, que você não
precisa se preocupar com questões de licenciamento e pode usá-lo (e copiá-lo) livremente.

Para fazer o download do Eclipse, acesse o endereço [Link] (caso esse link não
mais funcione, basta procurar pelo endereço atualizado).

Após entrar no site, obtenha a versão Standard (ou padrão). Escolha também a opção adequada ao seu
sistema operacional e à quantidade de bits usados (siga a mesma regra de quando obteve o JDK: se optou
pela versão de 64 bits, escolha o Eclipse também em 64 bits) e clique para iniciar o processo de download.
A figura 3 ilustra esse processo.

Figura 3 - Obtendo o Eclipse versão Standard. Fonte: [Link]

9
Java JSE: Programação Básica

Eclipse: IDE Java escrita em... Java!


Para executar o Eclipse, você precisa ter o Java instalado. Isso parece óbvio, já que o usaremos para
criar programas nessa linguagem. Mas tem outra coisa...
O Eclipse també foi escrito em Java!
Por isso, você precisa do Java não somente para compilar e executar os programas, mas também
para poder executar a ferramenta usada no desenvolvimento dos seus aplicativos.

Após clicar na versão desejada (32 ou 64 bits), você será redirecionado para outra página, na qual poderá
iniciar o download. Com base na sua localização, o site do Eclipse escolherá o servidor mais rápido dentre os
disponíveis. A figura 4 ilustra esse processo.

Figura 4 - Link para download do Eclipse. Fonte: [Link]

Terminado o download, você obterá um arquivo compactado (.zip) que já contém o Eclipse pronto para
ser executado. Crie uma pasta no local que preferir no seu computador e descompacte o arquivo dentro dela,
usando os recursos do seu sistema operacional ou um programa utilitário, como o WinZip ou o WinRAR. O
Windows pode descompactar arquivos .zip sem necessitar de utilitários: basta clicar com o botão direito do
mouse sobre o arquivo e selecionar Extrair Tudo (veja figura 5).

Figura 5 - Descompactando o pacote do Eclipse.

Na janela que será exibida, escolha (ou crie, após clicar em Procurar) a pasta na qual deseja colocar o
Eclipse e clique sobre o botão Extrair.

10
Java JSE: Programação Básica

Aviso importante!

Não coloque o Eclipse em uma pasta (ou dentro de um caminho de pastas) que contenha
espaços ou caracteres internacionais (como acentos e cedilha), pois ele pode apresentar
problemas de execução.

Terminada a descompactação, navegue até a pasta em que os arquivos foram extraídos. Você verá que
lá se encontra o programa executável da ferramenta, [Link] (veja figura 6), com o ícone de um globo.
Clicando duas vezes sobre ele, iniciamos o Eclipse. Mas não faça isso agora.

Eclipse: IDE Java escrita em... Java!


Para executar o Eclipse, você precisa ter o Java instalado. Isso parece óbvio, já que o usaremos para
criar programas nessa linguagem. Mas tem outra coisa...
O Eclipse també foi escrito em Java!
Por isso, você precisa do Java não somente para compilar e executar os programas, mas também
para poder executar a ferramenta usada no desenvolvimento dos seus aplicativos.

Figura 6 - O executável do Eclipse.

Como utilizaremos bastante o programa, crie um atalho para ele na Área de Trabalho. Para fazer isso
rapidamente, clique com o botão direito do mouse sobre o arquivo [Link]. Mantenha o botão clicado e
arraste o arquivo até a Área de Trabalho do Windows. Ao soltar o botão, surgirá um pequeno menu pop-up.
Selecione Criar atalho aqui... para que o atalho ao Eclipse seja criado.

Agora sim, pode clicar duas vezes sobre o atalho e abrir o programa para esta disciplina.

Conhecendo o Eclipse

Ao abrir o Eclipse pela primeira vez, você será questionado sobre a localização do seu workspace (espaço
de trabalho). Esse é o nome que o programa dá para uma pasta dentro do seu computador na qual ficarão
armazenados os seus projetos. Todo projeto criado será, por padrão, gravado dentro dela.

11
Java JSE: Programação Básica

O Eclipse sugere inicialmente que você use como seu workspace uma pasta nova com esse nome que será
criada dentro da pasta pessoal do seu usuário (veja figura 7, item 1). Se quiser, você pode mudar a pasta para
uma de sua preferência - apenas tome cuidado para não definir o workspace em um caminho que contenha
espaços ou caracteres de acentuação/cedilha, para evitar problemas futuros.

Figura 7 - Definindo o workspace do Eclipse. Fonte: Produção do autor.

Observe na figura 7 o item 2: trata-se de uma opção que, se marcada, definirá a pasta indicada como
workspace padrão e não perguntará mais por isso nas próximas inicializações. Se você tem certeza de que
esse será o melhor local para guardar seus projetos, marque essa caixa para que não tenha que confirmar o
workspace toda vez que abrir o Eclipse. Clique em OK em seguida.

Se você quiser mudar o workspace mais tarde, pode fazer isso clicando no menu File > Switch Workspace
> Other.

Depois de alguns segundos, você será apresentado à tela de boas-vindas do programa. Você pode fechá-
-la clicando no “X”, indicado na figura 8.

12
Java JSE: Programação Básica

Figura 8 - Tela de boas-vindas do Eclipse. Fonte: Produção do autor.

Agora você poderá visualizar a tela principal do Eclipse. Essa é a chamada perspectiva Java. Como o Eclip-
se tem uma grande variedade de recursos (podendo ser até usado para se criar programas em C/C++ ou
PHP), há uma série de possíveis configurações para sua tela principal. Cada uma é chamada de perspectiva e
adequada a uma determinada situação. A perspectiva Java, a mais usada por programadores, é a que vemos
na figura 9.

Figura 9 - Perspectiva Java do Eclipse. Fonte: Produção do autor.

13
Java JSE: Programação Básica

Veja na figura que temos uma barra de menus e Quanto à barra de menus e aos botões da bar-
logo abaixo uma barra de ferramentas, da mesma ra de ferramentas, conheceremos suas funções aos
maneira que na maioria dos aplicativos. A perspecti- poucos, à medida que desenvolvermos nossos apli-
va Java possui ainda quatro partes internas, indica- cativos.
das na figura 9 como a, b, c e d. São elas:
Criando o primeiro projeto no Eclipse
a) Package Explorer: é aqui que se visualizam
os projetos criados no Eclipse e seus arqui- Chegou a hora de testarmos esse IDE. Para confir-
vos. Todo programa Java criado nele será mar se o ambiente está funcional, faremos uma ver-
definido como um projeto, que consiste em são do tradicional “Alô, mundo!” utilizando o Eclipse.
um conjunto de arquivos de código-fonte,
configurações e bibliotecas, dentre outros. Crie um novo projeto Java no Eclipse clicando so-
b) Editor de código: nessa divisão central, são bre a seta para baixo logo à direita do primeiro botão
abertos os arquivos selecionados dentro de da barra de ferramentas e selecionando Java Project
um projeto, por meio do Package Explorer. no menu que será exibido, como indicado na figura
Na maior parte do tempo, você estará com 10.
arquivos com código Java abertos nesse lo-
cal, em que eles poderão ser editados.
c) Outline: mostra uma estrutura hierárquica
do código-fonte aberto. Por aqui, você pode
localizar rapidamente elementos existentes
no arquivo, como variáveis e métodos.
d) Problems/Console/JavaDoc - nessa
área, podem ser abertas diferentes abas,
porém aquelas com que você deverá ter
mais contato são as seguintes:
๐๐ Problems: aqui serão exibidos os erros e Figura 10 - Criando um novo projeto Java no
Eclipse. Fonte: Produção do autor.
os demais avisos sobre problemas exis-
tentes no código.
Em seguida, será mostrada uma janela, na qual
๐๐ Console: essa aba será aberta quando
deverá ser fornecido um nome para o projeto, em
você executar um aplicativo Java não
Project Name. Informe AloEclipse (dessa forma, sem
gráfico, que utiliza comandos de entrada
espaço e sem acento na letra o) e clique em Finish
e saída no console.
(veja figura 11). Repare que, em Location, estará in-
๐๐ JavaDoc: a importantíssima documenta-
dicado que o projeto será gravado em uma subpasta
ção da linguagem Java. Clicar em cima
com esse mesmo nome (AloEclipse) dentro do seu
do nome de uma classe ou método no
workspace.
código-fonte faz com que sua documen-
tação seja mostrada nessa aba (requer
que você esteja conectado à internet).

14
Java JSE: Programação Básica

Figura 11 - Criando um novo projeto Java. Fonte: Produção do autor.

Depois de alguns segundos, você verá o projeto AloEclipse, recém-criado, listado no Package Explorer.
Clique sobre a seta à esquerda do nome do projeto para exibir seu conteúdo (veja figura 12).

15
Java JSE: Programação Básica

Em Java, iniciamos o programa criando uma clas-


se com um nome qualquer que contenha um méto-
do especial: main(). Esse método foi definido para
que programas Java tenham um ponto de entrada,
ou seja, possam ter um local determinado para co-
meçar. Basta escrevê-lo dentro da primeira classe do
projeto (que se torna sua classe principal), seguindo
algumas regras básicas com relação à sua sintaxe.

A “mágica” ocorre por meio do interpretador


Java: quando executamos um aplicativo, ele busca
pelo método main() (que deve ter exatamente esse
Figura 12 - Projeto AloEclipse e seu nome) para poder iniciar a execução do programa.
conteúdo. Fonte: Produção do autor.
Por isso, criaremos uma classe de entrada no aplica-
tivo (que chamaremos neste exemplo de Principal) e,
Observe que nosso projeto contém apenas dois
dentro dela escreveremos esse método.
itens: uma pasta denominada src e uma referência
à biblioteca básica do JavaSE, de onde vêm as clas-
Mas, antes, é preciso outra coisa muito importan-
ses fundamentais da linguagem. O que nos interessa
te.
neste momento é a pasta src - é nela que colocamos
o código-fonte em Java, e podemos ver que por en-
Já sabemos que a classe é a unidade básica de
quanto não temos nenhum.
código em um programa Java. Como veremos mais
adiante, Java organiza as classes dentro de identifica-
Em Java, como em toda linguagem orientada a
dores, chamados pacotes. Um pacote é basicamente
objetos, trabalhamos escrevendo nosso código em
uma “classificação” para elas. Além de organizar me-
classes. Dentro destas, usamos outras classes (algu-
lhor os aplicativos e bibliotecas, possibilita que várias
mas criadas por nós mesmos, outras já existentes
classes sejam criadas com o mesmo nome sem que
dentro da biblioteca básica do Java) para definir o
ocorram conflitos (veremos como isso é possível mais
funcionamento do nosso programa. Na maioria das
à frente).
vezes, devemos instanciar as classes em objetos para
podermos usá-las. Em alguns casos, porém, não pre-
Por isso, antes de criar uma classe, precisamos
cisamos fazer isso: podemos usá-las diretamente.
criar a categoria na qual ela será arquivada, ou seja,
o seu pacote. Quando criamos um pacote dentro do
Por que estamos falando nisso agora, quando ain-
Eclipse, é criada uma subpasta dentro da pasta prin-
da não temos nem mesmo uma classe? Porque preci-
cipal de fontes do seu projeto. Quando uma classe
samos ter uma que sirva como “pontapé inicial”, que
for definida como pertencente ao pacote, será colo-
não será necessariamente usada para criar objetos,
cada dentro dessa pasta. Simples assim.
mas que contenha dentro dela o início do programa.

16
Java JSE: Programação Básica

Para criar um pacote, clique sobre a pasta src e em seguida sobre o botão New Java Package na barra de
ferramentas (como indicado na figura 13).

Figura 13 - Criando um novo pacote de classes Java. Fonte: Produção do autor.

Nomes de pacote devem ser definidos sempre com letras minúsculas - essa é a primeira de uma série
de convenções usadas pela maioria dos programadores Java que você deve seguir. Outra coisa: existe uma
forma padronizada de definir qual o nome de um pacote; veremos isso mais adiante. Por enquanto, defina-o
com o mesmo do projeto, só que em letras minúsculas (aloeclipse). Escreva o seu nome em Name e depois
clique em Finish (veja figura 14).

Figura 14 - Criando um novo pacote de classes Java. Fonte: Produção do autor.

17
Java JSE: Programação Básica

Observe à esquerda, no Package Explorer, que agora possuímos um pacote denominado aloeclipse dentro
da pasta src. Ele está vazio - precisamos colocar nossa classe dentro dele. No Package Explorer, clique sobre
o pacote aloeclipse; em seguida, clique sobre o botão New Java Class na barra de ferramentas (como na
figura 15). Com essa ação, indicamos ao Eclipse que queremos criar uma nova classe Java e que ela deverá
ser colocada dentro do pacote que selecionamos.

Figura 15 - Adicionando uma nova classe Java


ao projeto. Fonte: Produção do autor.

A janela mostrada na figura 16 será exibida. Nela,


podemos configurar vários aspectos da nova classe
a ser criada. Você pode perceber que, em razão de
termos selecionado o pacote aloeclipse no Package
Explorer, o Eclipse já detectou que essa classe per-
tencerá a ele (veja a configuração Package) e que
Figura 16 - Tela de criação de uma nova
seu arquivo correspondente ficará na pasta src do
classe. Fonte: Produção do autor.
projeto (indicado em Source Folder).

Diferenciação de maiúsculas e minúsculas e convenções do código Java

1. Java diferencia letras maiúsculas e minúsculas!


A linguagem Java é case sensitive. Portanto, nomes de classes, variáveis, métodos, objetos, ou seja, identificadores
em geral, devem sempre ser escritos levando em consideração essa diferenciação.
2. Siga as convenções sobre como usar maiúsculas e minúsculas.
Apesar de Java diferenciar maiúsculas das minúsculas nos nomes, o programador é livre para usá-las da maneira
que bem entender. Isso quer dizer que você pode criar uma classe chamada Principal ou PRINCIPAL.
Mas não é tão simples assim.
A maioria dos programadores (e a Oracle, até) segue um padrão de como usá-las. Um deles é sempre começar
o nome de uma classe com uma letra maiúscula. Esta disciplina foi escrita seguindo (e indicando) o uso desses
padrões conforme necessário, para que você vá se habituando aos poucos.

18
Java JSE: Programação Básica

Siga o que está indicado na figura 16 e informe o nome da classe (em Name) como Principal (dessa
maneira exata, com a letra P maiúscula e as restantes minúsculas). Também não se esqueça de marcar a
caixa indicada pela outra seta (public static void main...). Em seguida, clique sobre o botão Finish para que
a classe seja criada.

Ao selecionar a caixa de marcação public static void main..., indicamos ao Eclipse que essa classe deverá
ser criada contendo um método main() vazio, que servirá como “porta de entrada” ao nosso aplicativo. Como
você já sabe, esse é um método muito especial da linguagem Java e deve sempre ser declarado e escrito
seguindo uma sintaxe específica, para que a máquina virtual do JRE possa encontrá-lo (se ele existir) no seu
programa. Poderíamos ter deixado essa opção desmarcada e posteriormente adicionado o método manual-
mente, mas assim teríamos que saber exatamente como ele deve ser declarado.

O que são métodos?


Métodos são os nomes dados às funções desempenhadas pela classe, ou seja, às suas ações. Os métodos são as
implementações do que foi denominado operações em UML.

Veja o novo arquivo criado no seu projeto, o [Link]. Ele será aberto na tela central do Eclipse (veja
figura 17).

Figura 17 - Tela principal do Eclipse com o arquivo [Link] aberto.

Um arquivo .java é um arquivo de texto sem formatação, que pode ser editado com qualquer editor. Mas,
quando é aberto dentro do Eclipse, possui sua sintaxe colorizada e também passa a ser processado pelo
editor do programa; com isso, você recebe alguns avisos e dicas na barra cinza à esquerda do código.

19
Java JSE: Programação Básica

Veja, por exemplo, o ícone de um bloco de notas logo à esquerda da linha //TODO na figura 17. Isso
indica que o Eclipse a reconheceu como um tipo de comentário especial, usado para designar tarefas a ser
realizadas no software.

Configure o Eclipse para exibir os números das linhas do código

Um recurso importante do Eclipse, que vem desabilitado por padrão, é a exibição dos números das linhas do código,
à esquerda. Essa exibição ajuda em vários aspectos, como a localização de erros.
Habilite a exibição dos números de linha clicando no menu Window > Preferences do Eclipse. Na janela que será
aberta, clique sobre a chave General > Editors > Text Editors, à esquerda, e marque, à direita, a opção Show line
numbers.
Em seguida, clique em OK para que a numeração passe a ser exibida na coluna da esquerda do editor de código.

Aproveitando que os números de linhas apareceram, vamos entender o conteúdo desse arquivo a partir do
código mostrado no quadro 1.

Quadro 1 – Código-fonte do programa [Link]

1 package aloeclipse;
2 public class Principal {
3
4
5 public static void main(String[] args) {
6 // TODO Auto-generated method stub
7
8
9 }
10 }

• Linha 1: definimos que a classe existente nesse arquivo pertence ao pacote (package) aloeclipse.
• Linha 3: aqui, inicia-se a classe Principal. A palavra-chave public indica o seu encapsulamento (pú-
blico, ou seja, essa classe é acessível por qualquer outra). O identificador class indica que se trata,
obviamente, de uma classe, e deve ser seguido pelo nome dela. Ao final da linha, abrimos um bloco de
chaves que somente será fechado na linha 10.
• Linha 5: dentro de uma classe, definimos seu conteúdo (ou seja, seus atributos e operações). Nesse
caso, começamos a definir um método (operação). Esse método, como já vimos, é especial: serve
como ponto de entrada para a execução do programa. Por isso, sua declaração deve seguir esse pa-
drão: ser público (public), estático (static), não retornar valores (void) e chamar-se main, recebendo
como parâmetro um vetor de strings (String[]). O método começa nessa linha e termina na linha 8.

20
Java JSE: Programação Básica

Agora, vamos ao que interessa: programar. Logo abaixo da linha do comentário //TODO (que você pode
remover, se quiser), insira o comando do quadro 2.

Quadro 2 - Comando para exibição de caixa de mensagem

[Link](null, “Alô, Eclipse!”);

Poderíamos ter usado também [Link], que funcionaria normalmente. Mas vamos variar e ver
como fica melhor.

Estamos usando aqui uma classe do Java (ou seja, ela faz parte da biblioteca padrão da linguagem) cha-
mada JOptionPane. Ela é utilizada para exibição de uma pequena janela de mensagens e faz parte de um
framework (um conjunto de classes) chamado Swing - esse é o nome do pacote de componentes gráficos
que o Java usa para a criação de aplicativos em janelas.

O ponto ( . ) logo após JOptionPane indica que vamos usar um de seus métodos (ou seja, as ações que
essa classe sabe fazer). Nesse caso, estamos chamando o método showMessageDialog.

Esse método exibe uma pequena janela contendo o texto passado como segundo argumento (uma string
Java). O primeiro argumento pode ser mantido como null, pois somente é usado em casos em que a janela
de mensagem será exibida por outra janela.

Não podemos executar nosso projeto ainda. Existe um erro nele, como você pode ver pelo sublinhado em
vermelho na linha 7, como mostra a figura 18.

Figura 18 - Código do arquivo [Link]. Fonte: Produção do autor.

O Eclipse, além de detectar que existe um erro relacionado à classe JOptionPane, proporciona formas
automatizadas de tentar resolver o problema (trata-se de um recurso denominado Quick Fix). Você pode ver

21
Java JSE: Programação Básica

as sugestões de correção de duas formas: clicando e mantendo o cursor do mouse sobre o elemento com
erro ou clicando diretamente no símbolo da pequena lâmpada com um “x” na coluna da esquerda. Das duas
maneiras, será exibido um menu com sugestões de possíveis soluções, como na figura 19.

Figura 19 - Quick Fix para solução de erros no programa. Fonte: Produção do autor.

Não basta simplesmente clicar em qualquer uma das soluções e achar que tudo será resolvido. Você deve
saber o que está corrigindo, antes de tudo.

Esse erro está relacionado a um fato muito sim- Quadro 3 - Linha de importa-
ples: o Java está dizendo que não conhece a clas- ção da classe JOptionPane
se JOptionPane. “Mas como?”, você pergunta. “Você
não disse antes que JOptionPane é parte da biblio- import [Link];
teca padrão do Java?”. Ocorre que a classe está lá,
mas a nossa classe Principal ainda não foi informada Por que existe [Link] antes do nome da clas-
sobre sua existência. Isso é feito usando um coman- se? Trata-se do pacote ao qual ela pertence, pois não
do da linguagem Java chamado import, que faz com são só as classes criadas que pertencem a pacotes.
que uma classe passe a ser “reconhecida” dentro da
outra. Agora sim podemos executar o programa e ver o
que acontece. Só uma precaução antes: salve!
Clique sobre a primeira sugestão da lista, como
indicado na figura 19, e veja o que mudou no seu có- Você deve ter notado, no lado esquerdo do nome
digo. Primeiro: o erro sumiu. Segundo, a linha exibi- do arquivo [Link], na aba do editor de código,
da no quadro 3 foi adicionada ao código, logo depois um pequeno asterisco (*) (figura 20). Ele indica que
de package. o arquivo ainda não foi salvo.

22
Java JSE: Programação Básica

Figura 20 - Salvando todos os arquivos do seu projeto.

Habitue-se a salvar todo o conteúdo do seu projeto de tempos em tempos. Para isso, prefira usar sempre
o botão Save All, para salvar tudo de uma vez só, como indicado na figura.

Se não estivéssemos usando um IDE, agora seria o momento de compilar o arquivo .java para bytecode
(arquivo .class) e executá-lo com o interpretador java. Mas tudo isso é automatizado pelo IDE, clicando sobre
um simples botão do Eclipse: o Run (figura 21).

Figura 21 - Botão Run da barra de ferramentas do Eclipse. Fonte: Produção do autor.

Será aberta uma pequena janela, na qual o Eclipse pede que você informe o que está querendo executar.
Clique sobre Java Application e, em seguida, em OK (figura 22).

23
Java JSE: Programação Básica

Exercício: dado virtual

• Crie um projeto no Eclipse chamado Dado.


• Crie um pacote chamado dado (em letras mi-
núsculas).
• Adicione ao pacote dado uma classe chamada
Jogada, com um método main().
• Dentro desse método main(), você deverá exi-
bir ao usuário, usando um JOptionPane, um
número sorteado aleatoriamente de 1 a 6 (in-
cluindo estes), como se tivéssemos um dado
de seis lados.
• Para fazer o sorteio, pesquise como gerar valo-
res aleatórios com a classe Random.

Figura 22 - Executando o projeto como um


aplicativo Java. Fonte: Produção do autor.

Aula 3: estrutura básica de


Em poucos segundos, seu aplicativo será executa-
programação em Java SE
do e compilado, e uma pequena janela com a mensa-
gem “Alô, Eclipse!” será exibida (figura 23).
Instruções de entrada e saída em janelas

Para saída de dados no console (em modo apenas


texto), você já foi apresentado ao comando System.
[Link](), que imprime na tela o argumento pas-
sado a ele, seguido de uma quebra de linha.

Com a intenção de começar a usar recursos de


Figura 23 - Tela do aplicativo AloEclipse em execução. Fonte: interface gráfica, passaremos a utilizar a classe JOp-
Produção do autor. tionPane, que faz parte do framework Swing, o pa-
drão atual para construção de aplicativos em janela
Muito bem, agora você sabe como é criar um apli- em Java.
cativo Java usando uma ferramenta de desenvolvi-
mento integrado. A classe JOptionPane possui vários métodos es-
táticos para exibição de caixas de mensagens - pe-
quenas janelas contendo algum tipo de informação.

24
Java JSE: Programação Básica

O que são métodos estáticos?


Em resumo, métodos estáticos são aqueles executados diretamente de uma classe e não de um objeto instanciado
a partir dela. Falaremos mais sobre eles em breve.

O primeiro que conhecemos é o showMessageDialog(), que simplesmente exibe uma caixa de mensagem
contendo um texto e um botão OK. Ao clicar no botão, a janelinha é fechada. Ele é usado basicamente para
exibir informações e avisos, e você já conheceu seu funcionamento na aula anterior.

Existe também um outro método estático importante em JOptionPane que serve para a entrada de dados:
o showInputDialog(). Chamando esse método, uma pequena janela semelhante à do showMessageDialog()
será mostrada, com uma novidade: uma caixa de entrada de texto para que o usuário digite algo. Esse valor
digitado será devolvido como uma string por esse método. Veja sua sintaxe básica no quadro 4.

Quadro 4 - Sintaxe do método showInputDialog()

String nome = [Link](null, “Qual é o seu nome?”);

Na execução dessa linha, a caixa de mensagem exibida na figura 24 será mostrada.

Figura 24 - Caixa de entrada de texto exibida pelo método showInputDialog().

O usuário digita a informação na caixa e, após clicar no botão OK, o valor informado será retornado como
uma string. No código do quadro 4, guardamos esse retorno em uma string chamada nome.

Acrescente a linha do quadro 5 ao seu código e veja como, dessa maneira, criamos um pequeno progra-
minha muito bem educado.

Quadro 5 - Linha de mensagem com showMessageDialog

[Link](null, “Prazer em conhecê-lo(a), “ + nome);

25
Java JSE: Programação Básica

Use bastante o autocompletar do Eclipse

Neste ponto, você já deve ter visto o recurso de autocompletar em ação. Ele aparece alguns segundos após você
digitar um ponto depois do nome de um objeto ou classe ou quando está escrevendo qualquer identificador e
pressiona CTRL + ESPAÇO.

Tipos primitivos do Java, strings e conversão de valores

Você já conhece os tipos básicos (também chamados tipos primitivos) de Java, como int (para valores
inteiros), double (para valores decimais), char (para um único caractere) e boolean (para valores true, ver-
dadeiro, ou false, falso).

É importante lembrar que Java trata números literais sem ponto decimal como int e aqueles que possuem
ponto como double. Ou seja, int e double são os tipos default para valores numéricos colocados diretamente
no código. Por exemplo, o compilador Java vai considerar que estamos passando um int para o método no
quadro 6.

Quadro 6 - Exemplo de uso de literal int

[Link](5);

No exemplo do quadro 7, como o valor passado possui ponto decimal, será considerado como um double:

Quadro 7 - Exemplo de uso de literal double

[Link](9.5);

Você também já conhece uma string. Em Java, ela (que é uma sequência de caracteres alfanuméricos)
não é um tipo primitivo, mas, efetivamente, uma classe. Por isso, quando usamos e declaramos uma string,

26
Java JSE: Programação Básica

não estamos lidando com uma variável simples, mas com um objeto. A diferença é que objetos são mais
complexos e poderosos que variáveis de tipos primitivos.

Um recurso muito versátil das strings Java é sua possibilidade de concatenação, ou seja, de junção de
duas ou mais em uma nova. A concatenação é realizada usando o sinal de adição (+) entre elas. Veja o
exemplo no quadro 8.

Quadro 8 - Exemplos de concatenação de strings

String nome = “João”;

String sobreNome = “Silva”;

String nomeCompleto = nome + “ “ + sobreNome;

[Link](null, “Meu nome completo é “ +


nomeCompleto);

int idade = 22;

[Link](null, “Tenho “ + idade + “ anos de


idade.”);

O exemplo mostra várias situações em que usamos a concatenação de strings. O primeiro JOptionPa-
ne exibirá o texto “Meu nome completo é João Silva”. Já o segundo mostrará “Tenho 22 anos de idade”.
Veja que, mesmo idade sendo uma variável int, foi convertida automaticamente para string. Isso sem-
pre acontecerá em situações em que estivermos concatenando um valor numérico com outra string.

Apesar de a conversão no sentido valor numérico -> string ser automática quando esses valores são con-
catenados, há situações em que precisamos fazê-la manualmente. Isso ocorre principalmente na entrada de
dados.

Sabemos que o método showInputDialog() do JOptionPane retorna o valor informado com uma string.
Pois bem: suponha que estamos solicitando ao usuário um valor numérico que será usado em um cálculo
matemático. Não poderemos realizar operações matemáticas em um objeto string. Precisamos obter um
valor em um tipo numérico (int ou double, por exemplo) a partir desse valor.

Para obter o valor int equivalente a uma string, usamos o método parseInt(), existente na classe Integer
(uma classe utilitária para inteiros, usada também quando precisamos tratar um valor inteiro como um ob-
jeto, e não como um tipo primitivo int). Passamos a esse método a string contendo o valor numérico, e ele
nos devolve o int equivalente. O quadro 9 ilustra esse processo.

Quadro 9 - Exemplos de concatenação de strings

String dias = [Link](null, “Quantos dias atrasados p/ pagto.?”);


int diasEmAtraso = [Link](dias);

27
Java JSE: Programação Básica

Já no caso de double, usamos o método parseDouble(), disponível na classe Double (outra classe utilitária,
também utilizada nos casos em que é necessário um objeto contendo um valor com casas decimais), com
funcionamento semelhante ao anterior. Veja exemplo no quadro 10.

Quadro 10 - Exemplos de concatenação de strings

String valor = [Link](null, “Qual é o valor total da conta?”);


double valorDaConta = [Link](valor);

Conversões podem dar errado? Infelizmente, sim

Suponha que, no exemplo anterior, o usuário inadvertidamente forneça um número inválido como valor de conta,
incluindo, por exemplo, letras no campo de digitação. Exemplos: “12mmn”, “3.4Stt”, “asdasd”.
Nesses casos, não será possível realizar a conversão. Ocorrerá o que chamamos de exceção em Java. Para impedir
que o usuário receba uma mensagem de erro, precisamos tratar a exceção, ou seja, definir alguma ação caso ela
ocorra. Fazemos isso em Java usando a instrução try...catch.
Para o caso de uma conversão numérica, poderíamos tratar o erro de fornecimento de um valor inválido da seguinte
forma:

Conceitos básicos de memória, comparação de strings e strings mutáveis

Em Java, objetos, assim como variáveis, são alocados como espaços na memória do computador. Os
nomes que definimos para eles servem apenas como referências a essas áreas. É por esse motivo que não
devemos comparar duas strings em Java usando o sinal de igualdade (==), e sim o método equals, existente
nos objetos dessa classe.

Quando comparamos duas strings usando ==, não será feita uma comparação do conteúdo, mas sim da
posição de memória ocupada pelo objeto. Mas, quando usamos equals(), a comparação é feita precisamente
pelo conteúdo. Por isso, sempre que precisar comparar strings por valor em Java, prefira usar equals().

Mas há uma outra questão importante, também relativa ao uso de memória em Java. Toda vez que de-
claramos um objeto da classe String, estamos definindo uma cadeia de caracteres imutável. Isso significa
simplesmente que, após definir o conteúdo de uma string, não podemos mais modificar seu conteúdo. Ou

28
Java JSE: Programação Básica

seja, não podemos acrescentar, remover ou trocar caracteres dentro dela. Isso só pode ser feito por meio de
uma reatribuição.

Para entender melhor, veja o exemplo no quadro 11.

Quadro 11 - Exemplo de mudança de uma string usando reatribuição

String resultado = “”;


resultado = resultado + “Nome do candidato 1\n”;
resultado = resultado + “Nome do candidato 2\n”;

Suponha que estejamos construindo uma string que vai conter uma lista de nomes de candidatos aprova-
dos em um concurso. O código anterior resulta em uma lista impressa na tela semelhante a:

Nome do candidato 1
Nome do candidato 2

Pode-se tirar duas conclusões nisso: obteve-se o resultado pretendido e foi possível mudar o valor da string
resultado, pois concatenamos a ela duas linhas novas de texto. Mas isso não é realmente o que aconteceu.

A string resultado continua imutável. O que fizemos foi, nas duas últimas linhas do código, reatribuir um
valor a ela, composto do seu conteúdo anterior concatenado com a nova linha. Isso resulta em duas cópias
(para cada linha de concatenação) da variável na memória.

Em um exemplo como esse, ou com algumas poucas linhas a mais, não haveria grandes problemas em
relação a uso de memória e desempenho do programa. Porém suponha que estejamos montando uma string
resultante da concatenação (usando reatribuição) de centenas de linhas em um laço. Isso significa centenas
de cópias desnecessárias da variável na memória, com seu conteúdo crescendo exponencialmente, ou seja,
muita memória desperdiçada e sérios problemas de desempenho para o aplicativo.

Em casos como esse, é muito mais interessante usar a classe StringBuilder do Java, que foi criada justa-
mente para essa finalidade: proporcionar a criação de uma string mutável sem degradação do desempenho.
É, literalmente, um construtor de strings.

Para usar StringBuilder, basta instanciá-la em um objeto e usar o método append dela para que um novo
conteúdo seja concatenado à string, com mínimo prejuízo de memória e desempenho. O exemplo do quadro
11, usando StringBuilder, ficaria como apresentado no quadro 12.

29
Java JSE: Programação Básica

Quadro 12 - Criando uma string concatenada com StringBuilder

StringBuilder resultado = new StringBuilder();


[Link](“Nome do candidato 1\n”);
[Link](“Nome do candidato 2\n”);
String stringResultante = [Link]();

Posteriormente, para obter do objeto StringBuilder uma string tradicional, basta usar o método toString().

Uso do operador ternário

Ignorado por muitos, o operador ternário ? : é uma forma conveniente de se obter um resultado com
base no teste verdadeiro ou falso de uma condição, tudo em uma única linha. Pode ser usado para substituir
estruturas if...else, tornando o código mais conciso. Sua sintaxe é a seguinte:

resultado = condição ? valorSeVerdadeiro : valorSeFalso

Caso a condição seja avaliada como verdadeira, o resultado receberá valorSeVerdadeiro. Caso seja avalia-
da como falsa, receberá valorSeFalso. Exemplo prático em Java:

String resultadoDoAluno = (nota >= 6 ? “Aprovado” : “Reprovado”);

Projeto calculadora

Para praticar conversão de string para valores numéricos, uso de operadores aritméticos e concatenação
de strings, vamos implementar um projeto de uma calculadora simples que solicitará inicialmente dois nú-
meros ao usuário, por meio de [Link](), e exibirá, usando apenas um JOptionPane.
showMessageDialog, o resultado das quatro operações matemáticas básicas usando ambos. Ao final, o pro-
jeto deverá funcionar de modo semelhante à sequência de execução definida na figura 25.

Figura 25 - Sequência de execução para a calculadora, recebendo os números 16 e 2.

Para começar, crie um projeto chamado Calculadora. Dentro da pasta src desse projeto, adicione um paco-
te chamado calculadora. Por fim, nesse pacote, crie uma classe chamada Calc, contendo um método main().
Você deverá ficar com uma estrutura de projeto como a exibida na figura 26.

30
Java JSE: Programação Básica

Figura 26 - Estrutura do projeto Calculadora.

Nosso programa deverá executar as seguintes etapas:


• Obter o primeiro número. Caso o usuário digite caracteres inválidos, será exibido um aviso e atribuído
0 ao valor.
• Obter o segundo número, fazendo a mesma validação realizada para o primeiro.
• Calcular soma, subtração, divisão e multiplicação desses números.
• Montar uma string que exiba os resultados das quatro operações.
• Exibir a string ao usuário em uma janela.

Conseguiremos realizar facilmente esses passos usando os conceitos aprendidos até agora. Um forma de
implementar esse exercício é mostrada no quadro 13.

Quadro 13 – Código-fonte do arquivo [Link]

31
Java JSE: Programação Básica

Vamos entender o que está sendo feito nos principais pontos da listagem.

• Linhas 9 a 11: declaração de variáveis double para os valores e para os resultados das operações ma-
temáticas. Note que zeramos os valores de valor1 e valor2. Isso é necessário pois o uso do try...catch
na conversão de string para double (que temos posteriormente) faz com que o compilador Java indique
um possível cálculo com valor não inicializado nas operações. Além do mais, definimos anteriormente
que valores fornecidos incorretamente ficarão zerados, então já começamos com essa consideração.
• Linha 13: declaramos uma única variável string para poder apenas guardar o valor retornado pelos
métodos showInputDialog.
• Linhas 15 a 20: solicitamos o valor1 ao usuário. Caso seja informado um valor inválido, ocorrerá uma
exceção de formatação. Nesse caso, exibimos uma mensagem de alerta, indicando que o valor para o
número em questão ficará zerado.
• Linhas 22 a 27: fazemos o mesmo processo das linhas 15 a 20, só que agora para o segundo número
(variável valor2).
• Linhas 29 a 32: realizamos aqui as quatro operações matemáticas básicas usando os valores forne-
cidos.
• Linhas 34 a 38: para montar a string que será exibida ao usuário, contendo as quatro operações,
realizaremos várias concatenações. Por isso, como vimos anteriormente, nada melhor que utilizar um
objeto StringBuilder, juntando valores e símbolos por meio do seu método append. Veja que, ao final
da cada operação matemática, concatenamos também a string “\n”. Esse é um caractere de escape,
oriundo da linguagem C, que resulta em uma quebra de linha na impressão do texto.
• Linha 40: encerramos o programa exibindo a string criada no objeto StringBuilder.

Exercícios do Módulo 1

1) Projeto Potência:

• Crie um projeto no Eclipse chamado Potencia, com um pacote chamado potencia (em letras mi-
núsculas) e uma classe também denominada Potencia, com um método main().
• Dentro de método main(), solicite, usando um JOptionPane por vez, uma base e um expoente.
Armazene-os como tipo double.
• Caso o usuário forneça uma base ou um expoente inválidos, dê uma mensagem informando o
fato e dizendo que o programa será fechado.
• Se a base e o expoente forem válidos, calcule a potência usando os valores passados.
• Dica: Java possui uma classe chamada Math, com diversos métodos estáticos para funções ma-
temáticas. Um deles serve para calcular uma potência passando uma base e um expoente como
parâmetro. Use o autocompletar do Eclipse ou a documentação da linguagem Java para descobrir
qual é ([Link]
• Dica: para fechar um programa, basta usar return na função main() para encerrá-la.

32
Java JSE: Programação Básica

2) Projeto Conversor Celsius para Fahrenheit:

• No Brasil, usamos a escala Celsius para medição de temperatura. Nos Estados Unidos, contudo, é
utilizada a escala Fahrenheit. Usando uma simples fórmula matemática, é possível obter os graus
Fahrenheit a partir dos graus Celsius: Fahrenheit = ((Celsius * 9) / 5) + 32.
• Crie um programa Java no Eclipse que solicita os graus Celsius para o usuário e retorna os graus
Fahrenheit equivalentes.
• A partir deste momento, você deverá decidir que nome usará para seu projeto, pacote e classe.
Procure seguir as convenções no uso de letras maiúsculas e minúsculas.

3) Projeto Adivinhe o número:

• Neste exercício, vamos elaborar um “mini-jogo” de adivinhação.


• Sorteie um número de 1 a 50 (inclusive).
• Solicite ao usuário que tente adivinhar qual é esse número.
• Se o palpite for superior ao número sorteado, informe-o de que o número é inferior ao que ele
forneceu. Caso seja inferior, avise-o de que o número correto é superior.
• Quando ele acertar o valor, mostre quantas tentativas fez até aquele ponto e encerre o programa.
• Permita que o usuário desista de acertar ao fornecer o número 0 como palpite.

33
Java JSE: Programação Básica

4) Projeto Histograma:
• Um histograma (também chamado de diagrama de frequências) é um gráfico usado para visuali-
zar a quantidade de ocorrências de um conjunto de dados agrupado em classes. Vamos criar um
aplicativo que mostre um “histograma em modo texto”, exibindo quantas vezes números de 1 a
10 foram sorteados dentro de 100 sorteios possíveis.
• Você precisará repetir 100 vezes o sorteio de um número de 1 a 10 e guardar quantas vezes cada
um foi sorteado. Por exemplo, se o primeiro sorteio retornar 5, o contador de sorteios para 5 pas-
sará de 0 para 1. Se o segundo obtiver 2, o contador para 2 subirá de 0 para 1. Caso o terceiro
retorne novamente 5, incrementa-se mais uma vez o contador para 5, que ficará agora com 2. E
assim por diante. Prefira usar um vetor a variáveis individuais.
• Após realizar o sorteio, crie uma string que mostrará a quantidade de ocorrências para cada nú-
mero de 1 a 10. Ao invés de mostrar a quantidade de vezes que cada um foi sorteado, imprima
uma quantidade de cerquilhas equivalente. No exemplo da figura a seguir, o número 1 foi sorte-
ado 13 vezes; já o número 4, apenas quatro vezes.

• Dica: o “gráfico” é apenas uma string exibida com JOptionPane. Monte-a usando a classe StringBuilder.
• Dica: para ocasionar uma quebra de linha em uma string, concatene a ela um “\n”. Você precisará
disso para mostrar a frequência de cada número na sua própria linha.

34
Java JSE: Programação Básica

Módulo 2 – Classes e objetos em Java

A API do Java SE é riquíssima em número de classes prontas. As que vimos até agora são um pequeno
exemplo. Mas, mesmo contando com esse conjunto, a linguagem não traz classes relativas ao domínio de
um sistema, para produtos ou clientes em um sistema de vendas, por exemplo. O que Java contém são clas-
ses que auxiliarão o desenvolvedor a criar as suas, relativas à implementação do modelo conceitual de um
sistema projetado por meio da engenharia de requisitos e modelagem UML. Neste módulo, começaremos a
implementar em Java classes relativas ao sistema bancário, para que você tenha o entendimento essencial
de como transportar o modelo conceitual para a programação.

Aula 4 – Conceitos básicos de classes e objetos

Classes, objetos, métodos e instância


Você já sabe que, em orientação a objetos, os blo-
cos fundamentais de um sistema são suas classes. Convenções de código Java
Elas servem como moldes para os objetos, que são para classes
criados instanciando-as.
Você já sabe que, em Java, devemos nomear as
O objeto é como uma cópia ou instância de uma classes com a primeira letra maiúscula e as demais
classe, mas que possui um estado (também chamado minúsculas. Mas também precisa ficar sabendo que:
de conjunto de atributos, propriedade ou campo) que 1. Nomes de classe devem ser definidos no
dá a ele “vida própria” e características específicas. singular (Cliente é o correto, e não Clientes)
Além do estado, o objeto também possui operações 2. Para classes com duas ou mais palavras no
(também chamadas de ações ou métodos) que foram nome, capitalize sempre a primeira letra de
recebidas de sua classe e que permitem que realize cada palavra. Exemplo: ContaCorrente.
suas funções.
A classe Cliente terá, por enquanto, três campos
Em um sistema bancário, certamente teríamos ob-
(o nome pelo qual chamamos os atributos em Java)
jetos representando seus clientes. Assim, concluímos
e um método (que é como chamamos as operações).
que precisamos de um molde para eles: uma classe
Veja o diagrama UML para Cliente na figura 27.
Cliente.

Figura 27 - Diagrama para a classe Cliente. Fonte: Produção do autor.

35
Java JSE: Programação Básica

Se você olhou para a figura 27 e percebeu a falta de alguma coisa, tem toda a razão: não colocamos os
símbolos que especificam a visibilidade dos campos (público, privado ou protegido). Vamos deixar a classe
sem eles por enquanto - falaremos mais sobre a visibilidade em breve.

Aí vem a pergunta: como vamos criar essa classe em Java? Os campos serão variáveis dentro dela. Já o
método será uma função semelhante à main() que utilizamos até agora.

Com relação às variáveis, há um detalhe: as que criamos até o momento eram colocadas dentro de
main(). Isso faz delas locais ao método (ou seja, elas só existem e são visíveis dentro dele). Por isso, não
são consideradas campos das classes. As variáveis que representarão os campos são colocadas fora de seus
métodos. Geralmente, elas são declaradas no início da classe, logo após a chave de abertura.

A declaração básica de uma classe em Java obedece à sintaxe do quadro 14.

Quadro 14 - Sintaxe de declaração de uma classe em Java

class NomeDaClasse {
tipoDoCampo1 nomeDoCampo;
...
tipoDoCampoN nomeDoCampoN;

tipoDoRetornoDoMetodo1 nomeDoMetodo1(parametrosDoMetodo1) {
comando1;
comando2;
...
}
}

Uma classe pode conter quantos campos precisar. Cada objeto instanciado a partir dela possuirá seus
próprios valores armazenados em cada um dos campos. Por essa razão, eles também são chamados de va-
riáveis de instância.

O tipo de um campo pode ser um tipo primitivo (int, double, char, boolean), uma classe Java (string, ran-
dom...) ou até mesmo classes criadas por você dentro do seu programa.

36
Java JSE: Programação Básica

No nosso exemplo do Cliente, os campos nome, cidade e estado podem ser declarados como string.

Convenções de código Java para variáveis

Nomes de variáveis (tanto as locais em um método quanto as que são campos de uma classe) devem começar com
letras minúsculas, capitalizando as demais palavras.
Também devem ser evitados ao máximo nomes resumidos, que prejudiquem a legibilidade do código. Exemplos:
// Correto! É um bom nome de variável!
double saldoChequeEspecial;
// Errado! Não use maiúscula no início do nome - confunde com as classes!
double SaldoChequeEspecial;

Os métodos são como funções em linguagens de programação estruturadas, como C. Eles executam um blo-
co de comandos colocados dentro de suas chaves (delimitadores de início e fim) e podem retornar um valor,
que pode ser um dos tipos primitivos da linguagem ou objetos de classes. Métodos que não retornam valores
devem ser especificados com o tipo de retorno void.

Podemos ter um método em um objeto chamado calculadora (que pode ser, por sua vez, uma instância da
classe Calculadora), por exemplo, que retorna um resultado de um fatorial. Chamamos a execução colocando
um ponto após o nome do objeto e escrevendo seu nome, como no exemplo:

int resultado = [Link](6);

Nesse exemplo, chamamos o método calcularFatorial existente no objeto calculadora. Passamos a ele o
número 6 como parâmetro. Dentro do corpo do método, será feito o cálculo do fatorial desse valor, e o re-
sultado será retornado para ser guardado na variável resultado, do tipo int.

No caso da classe Cliente na figura 27, especificamos um método chamado listarDados, que vai trazer uma
ficha cadastral do cliente. Nesse caso, então, podemos assumir um retorno do tipo string para ele.

Uma classe pode conter vários métodos. Todo objeto instanciado a partir dela também os possuirá e os
poderá utilizar. Dentro de um método, podem ser usadas variáveis locais (declaradas e válidas apenas dentro
do método), valores passados ao método como parâmetro (válidos também somente dentro do método) e
campos da classe (lembrando que cada objeto instanciado possuirá seus próprios valores para eles) nos quais
o método está definido. Os argumentos ou parâmetros de um método, assim como seu retorno e variáveis
locais, também podem ser tipos primitivos ou objetos.

37
Java JSE: Programação Básica

Implementando a classe no sistema colocada dentro dele) clicando no botão


bancário da barra de ferramentas do Eclipse. Na jane-
la que será aberta, especifique o nome em
Para criar nossa classe Cliente, vamos começar a
Name e não deixe de marcar a opção public
implementação do nosso sistema bancário. Ele con-
static void main durante a criação para que
terá inicialmente duas classes: Principal e Cliente
tenhamos uma função main dentro dela.
(mesmo tendo outra classe, vamos continuar preci-
6) Em seguida, clique sobre o pacote banco.
sando de uma classe Principal com um método main
modelo e crie uma segunda classe. Dessa
para termos um ponto de entrada e uma interface
vez, dê a ela o nome Cliente e não marque
com o usuário).
a opção public static void main.
7) Terminando essas etapas, a estrutura do seu
O que são pacotes? projeto deverá ficar semelhante à exibida na
Pacotes são usados em Java para organizar classes e figura 28.
demais identificadores, além de possibilitar que duas
ou mais classes tenham o mesmo nome (desde que
pertençam a pacotes distintos). Podemos nomeá-los
usando subníveis, dividindo-os com pontos. Neste
exemplo, nosso sistema possui dois subníveis de
pacotes: modelo e tela, ambos pertencentes a banco.

Siga os passos:

1) Crie um novo projeto Java no Eclipse chama-


do SistemaBancario (sem acento e espaços
no nome).
Figura 28 - Estrutura inicial do projeto SistemaBancario.
2) Após criar o projeto, clique sobre a pasta
src e crie um pacote chamado [Link].
Agora, clique duas vezes sobre a classe Cliente.
Em seguida, adicione um segundo pacote,
java e vamos escrever seu código, de acordo com a
chamado [Link].
listagem mostrada no quadro 15.
3) No pacote [Link], colocaremos a
classe Cliente. O termo modelo é usado Quadro 15 - Código-fonte da classe Cliente
quando nos referimos aos elementos de um
programa relativos aos seus dados princi-
pais.
4) Já o pacote [Link] vai conter a classe
Principal, que por sua vez possuirá o método
main. Além de porta de entrada ao sistema,
essa classe e esse método atuarão como a
interface do aplicativo com o usuário. Por
essa razão, ela será colocada em um pacote
próprio, que representa melhor sua finalida-
de.
5) Crie a classe Principal (clique sobre o pacote
[Link] antes de criá-la, para que ela seja

38
Java JSE: Programação Básica

Vamos agora entender o que está sendo feito: Agora vamos colocar nossa nova classe em uso.
Abra a classe [Link] e escreva dentro do seu
• Linha 1: está indicado que a classe que será método main a seguinte linha:
definida a seguir pertence ao pacote banco.
modelo. Cliente cliente = new Cliente();
• Linha 3: nessa linha, inicia-se o código da
classe. Veja que a chave aberta ao final dela é Inicialmente, aparecerão sublinhados vermelhos
fechada apenas na linha 15. Tudo que estiver no lugar em que escrevemos Cliente. Isso ocorre
contido dentro desse par de chaves pertence à pois nossa classe Principal não a reconhece. Como
classe. Aí a iniciamos indicando que ela é pú- ela está em um pacote diferente, devemos acrescen-
blica (public). A palavra public determina que tar um import para ela.
poderá ser usada por qualquer outra. Depois
de public, class Cliente indica que estamos de- Você pode fazer isso de duas formas: usando a
finindo uma classe chamada Cliente. ajuda do Eclipse ou manualmente, adicionando a li-
• Linhas 4 a 7: como tínhamos colocado no dia- nha seguinte ao código, abaixo do comando package
grama da classe Cliente, declaramos aqui os [Link] e antes do início da classe:
três atributos que ela possui. Veja que todos
são do tipo string, adequado para o tipo de import [Link];
informação que conterão. Todo objeto instan-
ciado da classe Cliente possuirá seus próprios Perceba que, assim que você terminar de escrever
valores para esses campos. o comando, o erro na linha anterior irá desaparecer.
• Linhas 9 a 13: definimos um único método
Agora que não temos mais erros, vamos entender
para essa classe. Sua função é retornar uma
o que fizemos. Você simplesmente acabou de decla-
string listando os dados do cliente. A palavra
rar e instanciar (ou seja, criar) um objeto de uma
string, no início da linha 9 antes do nome do
classe sua. A sintaxe básica para declarar um objeto
método, indica que ele retornará um objeto
é a mesma da declaração de variáveis:
desse tipo. Veja que ele se chama obterDados
e, nesse caso, não recebe parâmetros (ou seja,
NomeDaClasse nomeDoObjeto;
nenhum valor precisará ser passado a ele quan-
do for executado). A chave no final da linha 9
A diferença aqui é que declaramos e instanciamos
indica o início do método, que é encerrado pela
o objeto em uma única linha. O instanciamento é
outra na linha 13.
feito pelo operador new e pelo método construtor.

No caso de métodos que retornam valores (ou


O método construtor é um comando especial da
seja, aqueles que não possuem void na sua declara-
classe, que serve para inicializá-la e que sempre tem
ção), devemos usar o comando return para devolvê-
o mesmo nome da classe. Poderíamos também ter
-los a quem os invocou. Nesse exemplo, montamos
escrito a linha:
uma string concatenando os dados do cliente (obti-
dos das variáveis locais do objeto: nome, cidade e
Cliente cliente = new Cliente();
estado) e retornamos para que possa então ser im-
pressa ao usuário. Note que o método listarDados() ...da seguinte forma, com o mesmo resultado:
pode acessar os campos, pois está contido na mesma
classe.

39
Java JSE: Programação Básica

Cliente cliente; te pertence ao pacote [Link] e Princi-


cliente = new Cliente(); pal, ao pacote [Link]. Resumindo: acesso
negado a campos e método.
Geralmente, é usada a primeira forma, que deixa
o código mais sucinto. É ela que usaremos nos nos- 33 Toda classe criada em Java sem uma super-
sos exemplos. classe (que é o caso aqui, por enquanto) herda
automaticamente a chamada “classe raiz” da
Agora, faça um teste: na linha seguinte, escreva linguagem, denominada Object e pertencen-
o nome do objeto (cliente) seguido de um ponto ( . ) te ao pacote [Link]. É dela que vêm esses
e aguarde a exibição da janela pop-up do autocom- métodos “estranhos” exibidos na figura 29.
pletar. Você deverá ver algo semelhante ao mostrado
na figura 29. Para poder usar os campos e o método existen-
tes em cliente de dentro da classe Principal, teremos
que colocar um modificador de visibilidade diferente
neles. Abra o código da classe Cliente e acrescente a
palavra public no início da declaração das variáveis e
do método, como indicado na listagem do quadro 16.

Quadro 16 - Listagem da classe Cliente com


modificadores de visibilidade nos seus membros

Figura 29 – Autocompletar ativo para o objeto cliente. Fonte:


Produção do autor.

Provavelmente você esperava ver os membros do


objeto cliente que ele possui, já que é uma instância
da classe Cliente. Esses membros seriam os campos
nome, cidade e estado e o método listarDados. Mas o
que você encontra? Um monte de nomes estranhos.
Mas não há nada de errado. Temos duas questões
importantes aqui:
Agora sim volte ao [Link], coloque o cursor
33 Você não está visualizando os campos e os
ao lado do ponto em cliente e pressione as teclas
métodos da classe Cliente pois, como não defi-
CTRL+ESPAÇO para ativar o autocompletar. Você
nimos a visibilidade deles, foi assumido um va-
verá os campos e o método disponíveis para uso.
lor padrão. Conhecido no Java como package
private, indica que um campo ou método sem Vamos colocar valores nos campos e executar o
especificador de visibilidade só poderá ser método listarDados. Adicione ao seu método main o
acessado por classes pertencentes ao mesmo código novo exibido na listagem do quadro 17.
pacote. Infelizmente, não é o caso aqui: Clien-

40
Java JSE: Programação Básica

Quadro 17 - Classe [Link]

Ao executar, você deverá obter uma janela semelhante à mostrada na figura 30.

Figura 30 - Tela de SistemaBancario em execução. Fonte: Produção do autor.

41
Java JSE: Programação Básica

Métodos construtores

Garbage collector

Toda vez que criamos um objeto com new, um espaço de memória é reservado para ele. Quando ele não é mais
usado, esse espaço deve ser liberado, por motivos óbvios de desempenho e economia de recursos do computador.
Nos primórdios das linguagens orientadas a objetos, o programador deveria se preocupar com esse fato: era
obrigação dele “jogar fora” um objeto que não estava mais sendo usado, para liberar memória. Com o tempo,
percebeu-se que essa prática prejudicava a produtividade, além de poder causar erros nos programas (por exemplo,
quando um programador colocava uma instrução para excluir um objeto quando ele ainda estava sendo usado).
Foram criadas técnicas para resolver essa questão, e Java, como boa linguagem moderna orientada a objetos,
implementa uma delas: a coleta de lixo.
Um elemento importante da máquina virtual do Java, o coletor de lixo (garbage collector, literalmente, lixeiro)
procura por objetos não mais utilizados no programa para que possam ser “jogados no lixo”, liberando a memória
por eles usada. Assim, você só precisa se preocupar em criar o objeto (usando o new). Deixe a preocupação de
excluí-lo com o “lixeiro” do Java.
Mas atenção: isso não significa que você pode “abusar”. Evite ao máximo instanciar objetos sem necessidade, para
não prejudicar o desempenho do aplicativo e do sistema no qual ele está sendo executado.

Um método construtor serve para inicializar os dados de um objeto recém-criado. No exemplo da classe
Cliente, não definimos um método construtor. Isso significa que o compilador Java vai criar um “construtor
vazio” automaticamente na nossa classe, com o seguinte conteúdo:

Repare em alguns detalhes:

33 O construtor é público (e é assim na maioria das vezes, apesar de que você pode criá-lo com outro
tipo de visibilidade).
33 Um construtor nunca possui retorno (nem mesmo void).
33 Seu conteúdo, nesse caso (dentro de chaves), está vazio.

Isso faz com que um objeto seja criado com seus campos totalmente vazios. Se quisermos, podemos
definir esse mesmo construtor dentro da classe Cliente colocando valores default nos campos. Suponha, por
exemplo, que a maioria dos clientes do banco seja de São Paulo, SP. Podemos então já iniciar o objeto com
esses valores, como exemplificado no quadro 18.

42
Java JSE: Programação Básica

Quadro 18 - Construtor padrão com inicialização de campos

A partir de agora, o construtor default vazio não será mais usado, e sim esse do quadro 18.

Podemos também escrever mais de um construtor, sempre com o mesmo nome da classe, mas usando
parâmetros diferentes. Isso se chama sobrecarga de métodos em Java.

Por exemplo, podemos manter esse construtor padrão sem parâmetros, mas termos também um segundo
no qual passamos os dados iniciais do cliente como parâmetros para que o objeto seja criado já com eles,
sem necessidade de definirmos um campo de cada vez. Para fazermos isso, adicione, dentro da sua classe
Cliente, o novo construtor exibido no quadro 19.

Quadro 19 - Novo construtor com parâmetros

Agora podemos usar qualquer um dos dois construtores. Se instanciarmos um objeto usando o sem parâ-
metros, devemos fazer desta forma:

Cliente cliente = new Cliente();

Assim, teremos um objeto cliente com os valores padronizados para os campos (por exemplo, com cidade
igual a São Paulo). Podemos modificar esses valores depois usando a atribuição direta. Mas podemos econo-
mizar tempo usando agora o segundo construtor da seguinte maneira:

Cliente cliente = new Cliente(“Anita”, “Marília”, “São Paulo”);

Nesse exemplo, o objeto cliente já começará com os valores para nome, cidade e estado, sem necessidade
de atribuição manual para cada um deles.

43
Java JSE: Programação Básica

Você pode até possuir métodos estáticos junto de


O que significa o this no construtor? não estáticos (listarDados, que criamos em Cliente, é
um destes) na mesma classe, mas os primeiros não
Repare que os parâmetros recebidos por esse
podem acessar variáveis de instância (ou seja, os
construtor mostrado no quadro 19 (que vão trazer os
valores iniciais para o objeto) possuem o mesmo nome campos) de um objeto. Para que um método estático
dos campos da classe. possa usar um campo da classe, este deve também
Se dentro do código do construtor fizéssemos
ser configurado como estático.
simplesmente
Um campo ou método é definido como estático
nome = nome;
colocando a palavra-chave static na sua declaração.
surgiria uma ambiguidade: estamos atribuindo quem Ao definir uma variável de uma classe como static,
a quem? O argumento ao campo ou o campo ao
você está dizendo que ela manterá um valor único
argumento?
- não existirão cópias específicas para cada objeto.
Usamos o this para eliminar a ambiguidade. A variável
especificada com this será considerada como o campo Por exemplo, poderíamos criar na nossa classe
da classe (this quer dizer este/esta - as variáveis
Cliente um campo estático do tipo int chamado quan-
existentes nesta classe). Assim, a atribuição será feita
tidade, que começará com zero e será incrementado
no sentido correto.
em um toda vez que um novo cliente for instanciado.
A existência desse campo abre também mais duas
Métodos estáticos
possibilidades interessantes:

Em alguns casos, não há necessidade de instan-


• Podemos usá-lo para definir um código único
ciarmos as classes em objetos para usarmos seus
para cada cliente instanciado.
métodos. Exemplos dessa situação que você já co-
• Podemos criar também em Cliente um méto-
nhece são os métodos de conversão de string para
do estático que retorna o valor desse campo
int e double: [Link] é uma chamada a um
quantidade - assim, poderemos saber a qual-
método estático da classe Integer, assim como Dou-
quer momento quantos objetos Cliente foram
[Link] invoca outro método estático, agora
criados.
da classe Double. Geralmente, métodos estáticos são
usados como métodos utilitários, pois não dependem Adapte sua classe Cliente para que contenha o có-
da existência de um objeto da classe. digo apresentado no quadro 20.

44
Java JSE: Programação Básica

Quadro 20 - Classe Cliente com campo e método estático

Vamos entender o que está sendo feito:

• Como agora teremos um campo para o código do cliente, ele é declarado na linha 5.
• Na linha 10, temos o campo estático do tipo int chamado quantidade. Essa variável vai guardar na
classe a quantidade de clientes já cadastrados. Não precisamos inicializá-la, pois, em Java, variáveis int
já começam contendo 0.
• Na linha 13, dentro do primeiro construtor (sem parâmetros), incrementamos a quantidade em 1. Isso
significa que, quando esse construtor for executado, terá sido realizada a criação de um novo cliente.
Na linha 14, aproveitamos e usamos o valor atual de quantidade como código do cliente. Repetimos
isso no outro construtor, nas linhas 21 e 22.
• Como agora temos uma informação adicional de um cliente (seu código), acrescentamo-la ao retorno
de listarDados(), na linha 29.
• Ao final, nas linhas 35 a 37, implementamos um método estático -qtdClientes() - que retorna a quan-
tidade de clientes guardada na variável.

45
Java JSE: Programação Básica

Para poder utilizar os novos recursos da classe Cliente, adapte sua classe Principal de acordo com a lista-
gem do quadro 21.

Quadro 21 - Classe [Link]

Execute seu projeto e veja o resultado.

Guarde bem seu sistema bancário!

Usaremos daqui em diante o sistema bancário em todos os próximos exemplos (inclusive os exercícios). Por isso,
não se esqueça de guardá-lo com cuidado. Faça sempre um backup de seu código!

Exercício prático - complementando o sistema bancário

• Crie uma classe Conta, dentro do pacote [Link], com os campos numero, cliente e saldo. O
campo cliente será um objeto da classe Cliente.
• Escreva um construtor para criar um objeto conta passando apenas um objeto cliente como parâmetro.
Nesse construtor, atribua como número da conta um número inteiro sequencial gerado automatica-
mente dentro da classe Conta. Atribua zero para o saldo inicial.
• Inclua em Conta um método para exibição dos dados dela, contendo: número, nome do correntista e
saldo.
• Em seguida, implemente na função main do sistema:

Três telas para solicitar as três informações do cliente: nome, cidade e estado.

46
Java JSE: Programação Básica

Uma tela para exibição da ficha de dados do clien- Importante: com o campo cliente em Conta, esta-
te (você já tem esse comando no seu código, se se- mos implementando uma associação entre as classes
guiu os exemplos anteriores). Conta e Cliente. Veja o diagrama UML:

Criação do objeto conta para esse cliente (não se


esqueça de atribuir o objeto cliente criado ao respec-
tivo campo da conta) e exibição dos dados da conta
logo em seguida, usando o método listarDados de
conta.

Aula 5 - Encapsulamento

Definição e exemplo de encapsulamento

O exercício que implementamos na aula anterior não está incorreto, mas possui um detalhe que pode ser
melhorado para que se encaixe melhor ainda na “vida real”. Você pode ter percebido que o campo saldo foi
declarado como público na classe Conta. Esse fato implica que, a qualquer momento, o usuário de um objeto
da classe Conta pode fazer o seguinte:

[Link] = 1000000000000;

Ou seja, o dono da conta pode modificar o saldo da conta quando quiser, para qual valor desejar, o que
com certeza é péssimo para o banco, o dono do sistema. Mas é principalmente ruim porque fere um princípio
importantíssimo da orientação a objetos: o encapsulamento.

O encapsulamento determina que os detalhes internos da implementação de uma classe devem ficar
ocultos ao usuário (ou seja, encapsulados), de forma que ele não possa prejudicar o seu funcionamento ou
sua lógica interna.

O exemplo da mudança arbitrária do saldo de uma conta é um exemplo de quebra do encapsulamento.


Sabemos que, em sistema bancário real, isso não pode ocorrer. O saldo só pode ser modificado mediante
o uso de transações, principalmente saque e depósito, e o banco (assim como o cliente) precisa que elas
fiquem registradas para que se possa controlar a movimentação da conta.

Modificadores de visibilidade: private, public e protected

Para ocultar ou limitar o acesso aos elementos de uma classe (tanto campos, como o saldo no exemplo
bancário, quanto métodos), usamos os modificadores de visibilidade. Em Java, temos as seguintes opções:

• public: o acesso ao membro da classe é irrestrito. Qualquer outra classe pode ter acesso livre a ele.
Isso implica, no caso dos campos, poder obter e modificar seus valores.
• private: é o modificador mais restritivo, pois oculta totalmente o campo ou método do “mundo exte-
rior”. Campos e métodos private só podem ser usados dentro da própria classe em que são definidos.

47
Java JSE: Programação Básica

• protected: permite o acesso ao membro dentro da sua própria classe (assim como private) e também
nas suas subclasses (classes criadas a partir dela - falaremos sobre herança na próxima aula).
• Sem modificador: quando não colocamos um modificador na declaração do campo ou método, o Java
assume-o como package private. Isso significa que o membro só pode ser acessado dentro da própria
classe e por outras classes pertencentes ao mesmo pacote.

Deve-se evitar ao máximo definir campos de uma


classe como public, pois assim se abre mão total-
Quadro 22 - Trecho inicial da classe Clien-
mente do controle do que pode ser colocado dentro
te com os campos modificados com private
dela. Para seguir o princípio do encapsulamento, o
ideal é definir os campos sempre como private ou
protected (neste último caso, para quando se for
criar uma subclasse que precisará usar um campo da
sua superclasse).

Mas, se colocarmos private em um campo, não


poderemos atribuir um valor a ele, nem mesmo aces-
sar seu conteúdo. Se você abrir a classe Cliente e
definir os campos como private, como no quadro 22,
perceberá que o Eclipse indica agora vários erros no
código da classe Principal (veja quadro 23).

Quadro 23 - Trecho do código da classe Principal em que surgem os erros

Não se preocupe. Faça essa mudança para que depois possamos contornar esse problema de maneira
muito mais eficiente do que simplesmente definir o campo como public: usando os métodos getters e setters.

Usando getters e setters

Um método getter - que poderia ser traduzido como “pegador” - é um método público existente dentro
de uma classe que é usado para outra obter um valor interno da primeira, ou seja, ele retorna um campo
private.

É um redirecionador: ao invés de obtermos o valor do campo diretamente (se for público), usamos o
getter como intermediário. Como? Adicione apenas as linhas 28 a 30 da listagem exibida no quadro 24 ao
seu arquivo [Link]. Você pode adicionar o método em qualquer ponto da classe, mas a convenção mais
usada é colocá-los após o(s) construtor(es).

48
Java JSE: Programação Básica

Quadro 24 - Classe Cliente com método getter para o campo nome

Agora, quando uma outra classe precisar obter o nome de um cliente, deverá executar o método getNo-
me() dentro do objeto. Veja na linha 29 que esse método retorna o conteúdo do campo nome.

Exemplo de uso:

String nomeDoCliente = [Link]();

Convenções de código Java: dando nome a um getter

É uma convenção de Java que métodos getter devem ter seu nome definido da seguinte forma:

• Começando com get em letras minúsculas.


• Seguindo com o nome do campo com sua primeira letra maiúscula.
Por exemplo, considere o seguinte campo:
private int idade;
Seu getter deverá se chamar getIdade (repare na letra I maiúscula), e seu código ficaria dessa forma:
public int getIdade() {
return idade;
}

Você pode perguntar: qual a utilidade então de se usar um getter, já que o valor do campo será retornado
de qualquer jeito?

Dessa maneira padrão, realmente não há mudança. Mas, dessa forma, o acesso ao campo fica controlado
e, se quisermos, podemos dentro do getter determinar como o conteúdo deverá ser apresentado ao usuário.
Por exemplo, podemos fazer uma formatação do valor antes de ele ser retornado.

49
Java JSE: Programação Básica

Suponha que quiséssemos retornar apenas o primeiro nome do cliente (apesar de estar armazenado em
nome seu nome completo). Podemos modificar o getter para o exemplo do quadro 25.

Quadro 25 - Implementação de getter para nome com retorno formatado

O método substring, existente em todo objeto da classe String, retorna uma parte dela existente entre
o índice do primeiro parâmetro, 0 no exemplo, e o índice anterior ao segundo parâmetro. [Link](‘ ‘)
será a posição dentro da string em que ocorre o primeiro espaço (se ele contiver um espaço; caso contrário,
retornamos o valor completo - tudo isso testado com um operador ternário).

Para permitir a modificação de um valor de um campo oculto, usamos os métodos setters (poderíamos
traduzir como “definidores” ou “modificadores”). Assim como os getters, os setters são geralmente definidos
como públicos (public). Como nesse caso não há retorno de valor, colocamos a palavra chave void na sua
declaração.

O valor que vai ser colocado no campo privado é passado como um parâmetro ao setter. Dentro do seu
corpo, atribuímos o valor do parâmetro ao campo da classe. Veja no quadro 26, nas linhas 32 a 34, o setter
para o nome do cliente, colocado dentro da classe Cliente logo após seu getter.

Quadro 26 - Trecho de código da classe Cliente com setter para o campo nome implementado

Perceba que, assim como fizemos no construtor que criamos para Cliente, usamos o mesmo nome do
campo local da classe para o parâmetro (nome). Por isso, para não causar ambiguidade e definirmos que o
campo local é que receberá o parâmetro (e não o contrário), usamos this na linha 33.

50
Java JSE: Programação Básica

Convenções de código Java: dando nome a um setter

Assim como nos getters, é uma convenção de Java que métodos setter devem ter seu nome definido da seguinte
forma:

• Começando com set em letras minúsculas.


• Seguindo com o nome do campo com sua primeira letra maiúscula.
Por exemplo, considere o seguinte campo:
private double media;
Seu setter deverá se chamar setMedia (repare na letra M maiúscula), e seu código ficaria dessa forma:
public void setMedia(double media) {
[Link] = media;
}

Novamente, você pode achar que dessa maneira estamos apenas “trocando seis por meia-dúzia”. A forma
default do setter, como implementada no quadro 26, realmente não faz nenhum controle do que é colocado
em nome, mas permite que facilmente implementemos isso, sua grande vantagem, como no exemplo do
quadro 27.

Quadro 27 - Implementação de setter para o campo nome de Cliente com validação

No exemplo, antes de atribuir o parâmetro ao campo, o setter verifica se o primeiro foi passado vazio.
Caso tenha sido, atribui “não fornecido” ao nome; caso contrário, coloca nesse campo o valor fornecido como
argumento.

Agora que temos um setter para o campo nome, podemos começar a corrigir os problemas na classe Prin-
cipal. Troque a linha em que colocávamos diretamente o valor retornado pelo JOptionPane no campo nome
pela chamada ao setter, como na linha 23 da listagem do quadro 28.

Quadro 28 - Classe Principal com uso do setter para o nome do cliente

51
Java JSE: Programação Básica

Exercício adicional

Adicione getters e setters para os demais campos da classe Cliente e modifique a classe Principal para
usá-los. Você notará que também há um erro na classe Conta. Consegue descobrir por quê? Após terminar,
confirme o resultado nas listagens dos quadros 29, 30 e 31.

Não crie getters e setters sem necessidade!

Você deve sempre deixar os campos das classes como private ou protected, mas nem sempre precisa criar getters
e setters para eles. Apenas crie se for realmente usá-los, ou seja, se alguma classe externa precisar obter e/ou
modificar os valores.
Por exemplo: na classe Cliente, não precisamos criar getters e setters para os campos codigo e quantidade, pois em
nenhum momento em Principal ou Conta fazemos referência direta a esses valores.

Quadro 29 - Trecho da classe Cliente com getters e setters necessários

Quadro 30 - Trecho da classe Principal usando setters para nome, cidade e estado

52
Java JSE: Programação Básica

Quadro 31 - Trecho da classe Conta usando getter para o campo nome de cliente

Encapsulamento de campos na prática: exercício prático guiado

Agora, precisamos fazer algumas modificações no nosso sistema bancário, por três motivos:

• Para que ele fique ainda mais semelhante ao modelo UML.


• Para prepará-lo para a implementação prática do assunto da próxima aula: herança.
• Para podermos praticar mais um pouco o conceito de encapsulamento.

Vamos impedir que o usuário da classe Conta possa manipular o saldo diretamente. A partir de agora, ele
deverá obrigatoriamente usar métodos para tanto (saque ou depósito). Futuramente, quando você for apre-
sentado ao conceito de interfaces em Java, poderá transformar esses métodos saque e depósito em classes
que implementam a interface Transação.

Deixaremos as classes do nosso sistema semelhantes às apresentadas na figura 31.

Figura 31 - Diagrama UML para as classes Cliente e Conta.

Veja que agora temos o símbolo indicando a visibilidade desejada para os campos e métodos, assim como
seus tipos. Não foram colocados todos os métodos no diagrama (como getters, setters e construtores) para
nos focarmos naquilo que precisaremos incluir ou modificar, ou seja:

• Como criaremos subclasses para Conta e Cliente na próxima aula, mudaremos a visibilidade de seus
campos para protected.
• Para manipulação do saldo, deveremos implementar dois métodos públicos em Conta:
๐๐ sacar(), que receberá um valor double de saque como parâmetro e somente o realizará (sub-
traindo o valor do parâmetro do saldo) se houver saldo suficiente. Note que esse método deverá
retornar um boolean: true, se o saque foi realizado (havia saldo disponível), ou false, caso con-
trário (o saldo era insuficiente). Podemos usar esse retorno na interface para avisar ao usuário
sobre a realização ou não.
๐๐ deposito(), que receberá uma valor double de depósito como parâmetro. Nesse caso, não há
retorno no método - basta adicionar o valor do parâmetro ao saldo.

53
Java JSE: Programação Básica

Após movimentar sua conta, o usuário desejará ver como ficou seu saldo. Para isso, teremos o método
getSaldoFormatado, que retornará uma string com o saldo da conta em formato monetário.

Antes de continuar, tente fazer essas mudanças sozinho, implementando um procedimento de depósito e
saque na classe Principal. A seguir, teremos um passo a passo de como implementar o que foi pedido.

1º passo: adaptando a classe Cliente

Abra a classe Cliente e altere seu código seguindo o exemplo da listagem do quadro 32. Nesse caso, é
bastante simples: basta mudar os modificadores de visibilidade dos campos. Repare que manteremos o cam-
po estático quantidade como private; não é necessário colocá-lo como protected, e na próxima aula você
descobrirá o porquê.

Quadro 32 - Mudanças na classe Cliente

2º passo: adaptando a classe Conta

Vamos agora passar à classe Conta. Primeiro mudaremos os modificados de visibilidade dos campos,
como indicado no quadro 33.

Quadro 33 - Modificações de visibilidade dos campos na classe Conta

Veja que colocamos o contador como private, pela mesma razão de termos definido o de Cliente dessa
forma.

O principal vem agora: a implementação dos métodos de obtenção do saldo formatado, de saque e de de-
pósito. Acrescente-os logo no final da classe Conta, após o método listarDados(), de acordo com o quadro 34.

54
Java JSE: Programação Básica

Quadro 34 - Novos métodos na classe Conta

Explicações do código do quadro 34:

• Como definimos o saldo como protected, não poderemos acessá-lo diretamente a partir da classe Prin-
cipal. Seria interessante ao cliente visualizar seu saldo atual após uma operação de saque ou depósito.
Por isso, adicionamos o método getSaldoFormatado(), definido nas linhas 26 a 28, cuja função é retor-
nar uma string com o saldo da conta em formato monetário.
• O método depositar (linhas 30 a 32) é bastante simples: recebe um valor double como parâmetro e
adiciona-o ao saldo da conta.
• Para realizar um saque, será usado o método sacar (linhas 34 a 41) que também recebe um valor como
argumento. Porém o saque somente será possível se o saldo for superior ou igual ao valor passado.
Nesse caso, subtraímos o valor do saque e retornamos true, sinalizando que a operação foi realizada
com sucesso. Se o saldo for inferior, caímos no else da linha 34 - nesse caso, não é feita mudança no
saldo, e o método retorna false.

3º passo: testando as implementações na classe Principal

Para testar a implementação, vamos adicionar à classe Principal, logo após a criação dos objetos cliente e
conta, um pequeno “menu de movimentação” da conta, com opções para realizar um saque ou um depósito
ou finalizar o programa.

Acrescente à classe Principal, logo após a exibição dos dados da conta instanciada, o código exibido no
quadro 35.

55
Java JSE: Programação Básica

Quadro 35 - Código da classe Principal com menu de movimentação da conta

Explicações do código do quadro 35:

• Linhas 34 e 35: declaramos duas variáveis auxiliares - uma int para a opção escolhida no menu e uma
string para receber o valor digitado pelo usuário no JOptionPane.
• Linha 36: iniciamos um laço que termina na linha 58 e que se repetirá enquanto a opção de menu es-
colhida pelo usuário for 1 (depósito) ou 2 (saque).
• Linhas 37 e 38: montamos uma string com o menu de opções.
• Linha 39: abrimos um bloco try para tratar erros de conversão de valores. Caso o usuário forneça um
valor que não possa ser convertido para número (nas opções menu ou valores), o fluxo de execução
do programa será direcionado para o catch na linha 55, que exibe um aviso.
• Linha 40: usando um JOptionPane, solicitamos a opção do usuário. O retorno já é convertido para int
e armazenado na variável opcao.
• Linha 41: abrimos um switch...case que é encerrado apenas na linha 54. Ele fará o tratamento adequa-
do da opção do menu escolhida pelo usuário.
• Linhas 42 a 46: se a opção for igual a 1, o usuário escolheu fazer um depósito. Após obter o valor com
um JOptionPane e convertê-lo para double, passamos para o método sacar existente no objeto conta,
que faz a mudança no saldo. Avisamos o usuário de que o saque foi realizado com outro JOptionPane.
O comando break logo em seguida impede que o fluxo de execução passe ao case seguinte.
• Linhas 47 a 53: no caso da opção 2 (saque), inicialmente solicitamos o valor desejado ao usuário e
fazemos sua conversão para double. Como o método sacar retorna um boolean indicando seu o saque
teve sucesso ou não, fazemos a chamada a ele diretamente na condição do if. Se o retorno for verda-
deiro, o saque foi realizado; caso contrário, falhou. Em ambos os casos, avisamos o usuário sobre o
ocorrido.

Assim, finalizamos juntos a tarefa de melhorarmos ainda mais nosso sistema bancário.

56
Java JSE: Programação Básica

Exercício do Módulo 2

Crie um aplicativo Java para um jogo de forca. Nele, você deverá ter uma classe Principal, na qual acon-
tecerá a interação com o usuário, e uma classe Forca, em que ficarão os dados principais do jogo.

• Na classe Forca, você deverá implementar:


• Uma lista de palavras disponíveis para o jogo (um vetor de strings, por exemplo).
• Um contador de erros.
• Um construtor, em que será sorteada a palavra a ser adivinhada dentro da lista de palavras disponíveis.
• Um getter que trará uma representação do “estágio de enforcamento”, dependendo da quantidade de
erros do usuário. Serão sete estágios, indo da forca vazia (nenhum erro) à completa (seis erros):
๐๐ Sem erro: desenho da forca vazia.
๐๐ Um erro: forca com cabeça.
๐๐ Dois erros: forca com cabeça e tronco.
๐๐ Três erros: forca com cabeça, tronco e braço direito.
๐๐ Quatro erros: forca com cabeça, tronco, braço direito e braço esquerdo.
๐๐ Cinco erros: forca com cabeça, tronco, braço direito, braço esquerdo e perna direita.
๐๐ Seis erros: forca com cabeça, tronco, braço direito, braço esquerdo, perna direita e perna es-
querda.
• Você pode exibir uma string contendo o desenho ASCii da forca diretamente em um JOptionPane, po-
rém o desenho sairá “torto”, já que essas janelas não usam fontes de largura fixa. O ideal é usar um
componente JTextArea junto do JOptionPane, pois pode ser configurado para uso de fonte de largura
fixa.
• Na classe Principal, comece mostrando a forca vazia e um conjunto de traços representando a palavra
sorteada. Por exemplo, se a palavra for JAVA, exiba _ _ _ _.
• Peça uma letra ao usuário.
• Veja se a letra informada existe dentro da palavra sorteada na classe Forca. Use métodos de objetos
string para isso, como contains().
• Se existir, mostre abaixo da forca os traços da palavra sorteada com a substituição do(s) traço(s) res-
pectivos pela letra.

Caso não exista, incremente o contador de erros e mostre o novo estágio de enforcamento.

Se o usuário não descobrir até o último estágio, encerre o jogo e mostre a palavra secreta.

Veja a seguir um exemplo inicial da classe Forca e da classe Principal, para você começar sua implemen-
tação. Não se esqueça de que o exemplo mostra apenas o desenho do primeiro e do último estágio da forca.
Você deverá “desenhar” os demais.

Logo após o exemplo de classe para a Forca, você encontrará também um exemplo de código que mostra
como usar o JTextArea junto do JOptionPane, de modo que o desenho ASCii apareça alinhado corretamente.

57
Java JSE: Programação Básica

58
Java JSE: Programação Básica

Módulo 3 – Herança e polimorfismo

Neste módulo, conheceremos como Java implementa dois dos mais poderosos recursos da programação
orientada a objetos: herança e polimorfismo. Ao final das próximas duas aulas, você terá evoluído seu sis-
tema bancário ainda mais dentro da modelagem realizada na disciplina de UML. Assim como na última aula,
as implementações serão feitas na forma de exercícios guiados, que você poderá tentar realizar sozinho ou
seguindo as orientações do material.

Aula 6 – Herança em Java

Conceito de herança

A herança possibilita que você crie uma classe utilizando outra como base. É uma das formas mais fre-
quentes de reutilização de código e uma maneira de tornar os programas mais organizados e fáceis de ser
mantidos e atualizados.

Para criar uma relação de herança, estabelecemos primeiro uma generalização de um elemento de um
sistema. Em seguida, criamos as versões especializadas desse elemento, que recebem então, de forma direta
e automática, as características do primeiro.

Na figura 32, você pode verificar um diagrama de classes UML com dois exemplos de herança e generali-
zação já adequados à implementação que estamos fazendo até este ponto.

Figura 32 - Sistema bancário com herança de classes. Fonte: Produção do autor.

No caso de Cliente, criamos duas classes especializadas: uma para cliente pessoa física (denominada
PessoaFisica) e outra para cliente pessoa jurídica (chamada PessoaJuridica). Deixamos essa classe ainda
mais genérica, contendo apenas os campos comuns aos dois tipos (codigo, cidade e estado) - perceba que
movemos o campo nome, específico de pessoas físicas, para a classe correspondente.

59
Java JSE: Programação Básica

Assim, quando instanciarmos um objeto da classe Há a possibilidade de, dentro da subclasse, utilizar
PessoaFisica, teremos, além dos campos e métodos recursos na superclasse, desde que sejam declarados
existentes em Cliente, campos adicionais para nome como protected ou public. Para tanto, utiliza-se a pa-
e CPF. Já quando criarmos um objeto da classe Pes- lavra chave super.
soaJuridica, receberemos, além do que já existe em
Cliente, um campo para o CNPJ e outro para a razão Vamos agora implementar juntos no sistema ban-
social. cário a herança para os dois tipos básicos de cliente.

A classe Conta também é um exemplo que pode Exercício prático guiado: herança de
ser especializado com herança. Isso porque, em um cliente no sistema bancário
banco, o cliente pode abrir tanto uma conta corrente
quanto uma conta poupança, sendo que cada uma Vamos começar a implementação da nossa heran-
possui características próprias. ça em Java generalizando mais a classe Cliente. Abra
seu código-fonte e exclua a declaração do campo
Observe na figura 32 que criamos uma classe nome, assim como seu getter e seu setter. Também
ContaCorrente, que herda da classe Conta e que a remova a utilização deste dentro dos dois construto-
complementa com os campos limite e juros, assim res existentes na classe e seu uso dentro do método
como traz o método aplicarJuros(). Já a classe Con- listarDados. Sua classe Cliente deverá ficar como a
taPoupanca também herda as características básicas listagem exibida no quadro 36.
da classe Conta, mas acrescenta campos para a data
de aniversario (tipo classe Date de Java - um objeto Quadro 36 - Listagem da clas-
dessa classe armazena uma data específica) e o ren- se Cliente sem o campo nome
dimento, assim como um método para aplicar os ren-
dimentos ao saldo (aplicarRendimentos). Implemen-
taremos as classes ContaPoupanca e ContaCorrente
na próxima aula, quando tratarmos de polimorfismo
em Java.

Superclasses e subclasses

Existe uma terminologia para nos referirmos às


classes participantes em um esquema de herança.
Chamamos a classe mais genérica, aquela que possui
as características que serão herdadas pelas demais,
de superclasse. No exemplo da figura 32, Cliente é a
superclasse.

As classes especializadas, que herdam da super-


classe, são chamadas de subclasses. Portanto, Pes-
soaFisica e PessoaJuridica são subclasses da classe
Cliente.

60
Java JSE: Programação Básica

Não se preocupe com erros que podem aparecer nas outras classes: vamos corrigi-los daqui a pouco.

Agora, vamos adicionar a classe PessoaFisica. Clique em cima do nome do pacote [Link] à esquer-
da, no Project Explorer, e clique sobre o botão New Java Class do Eclipse. Se não se lembra de como fazer
isso, oriente-se pela figura 33.

Figura 33 - Adicionando uma nova classe Java ao pacote [Link] do projeto. Fonte: Produção do autor.

Na janela que será mostrada, especifique o nome da classe como PessoaFisica em Name e clique em Fi-
nish para que a classe seja criada.

A classe recém-criada inicia-se sem especificação de herança (mas, mesmo assim, ela ainda herda a classe
básica do Java, [Link]). Nesse caso, precisamos especificar que PessoaFisica herda Cliente.

61
Java JSE: Programação Básica

Em Java, a palavra-chave extends é usada para indicar a superclasse de uma classe, ou seja, de quem ela
herda suas características iniciais. Para fazer isso, inclua o código extends Cliente na sua declaração, como
na linha 3 do quadro 37.

Quadro 37 - Classe PessoaFisica herdando a classe Cliente

Pronto, PessoaFisica passou a conter tudo que já existia em Cliente.

Agora, implemente o restante do código para PessoaFisica seguindo a listagem do quadro 38.

Quadro 38 - Código completo da classe PessoaFisica

62
Java JSE: Programação Básica

No quadro 38, temos em PessoaFisica os campos Já na linha 15, dentro do construtor PessoaFisi-
adicionais nome e cpf, assim como seus respectivos ca (string cidade, string estado, string nome, string
getters e setters. Até aí, nenhuma novidade. Mas veja cpf), chamamos o segundo construtor de Cliente,
os dois métodos construtores: um sem parâmetro, aquele que recebe uma cidade e um estado como
que cria o objeto com valores default, e outro em que parâmetros. Fazemos isso pois também precisamos
o usuário pode passar os dados do cliente para que criar o cliente PessoaFisica com uma cidade e um
seja criado já com todas as informações necessárias. estado, de acordo com aquilo que o usuário passou
como argumentos no construtor dessa classe.
Percebeu a novidade? O comando super do Java!
Como seu próprio nome dá a entender, ele é usado Veja que, nas linhas 36 a 38, implementamos uma
para nos referirmos aos elementos existentes na nos- nova versão de listarDados(), específica para clien-
sa superclasse. tes pessoa física. Ela vai trazer os dados específicos
de PessoaFisica (nome e cpf) junto daqueles que já
O comando super(), na linha 9 dentro do cons- existiam em Cliente, obtidos pela chamada a esse
trutor PessoaFisica(), por exemplo, executa antes de método usando [Link].
tudo o construtor sem parâmetros existente na su-
perclasse Cliente. Isso ocorre para inicializar também Para completar, vamos agora criar e escrever o
cidade e estado, assim como incrementar a quantida- código para PessoaJuridica. Siga a listagem do qua-
de de clientes criados e atribuir um código para eles. dro 39.

Quadro 39 - Código-fonte da classe PessoaJuridica

63
Java JSE: Programação Básica

A classe PessoaJuridica é estruturada de forma bem semelhante à PessoaFisica: acrescentamos seus


campos específicos (cnpj e razaoSocial) getters e setters para eles e construtores que também utilizam o
comando super. Também temos uma versão específica de listarDados(), que agora trará também a razão
social e o CNPJ.

Para testar o uso das duas classes, vamos modificar o método main, dentro da classe Principal, para que o
usuário possa escolher, assim que o sistema for iniciado, se irá cadastrar um cliente pessoa física ou pessoa
jurídica.

Altere seu método main, na classe Principal, para que ele fique como na listagem do quadro 40.

64
Java JSE: Programação Básica

Quadro 40 - Código da classe Principal com uso das classes PessoaFisica e PessoaJuridica

65
Java JSE: Programação Básica

Os principais pontos nos quais ocorreram mudanças significativas são:

• Linha 14: começamos instanciando um objeto da classe Cliente. Criamos um objeto genérico, pois
ainda não sabemos se o cliente será pessoa física ou pessoa jurídica. De qualquer maneira, será um
cliente, por isso esse objeto será útil em qualquer um dos casos.
• Linha 16: exibimos um JOptionPane para que o usuário escolha o tipo de cliente que está cadastran-
do. Se informar a letra “F”, é um cliente pessoa física; caso digite “J”, será pessoa jurídica. O valor
digitado fica guardado na variável tipoCliente, uma string.
• Linhas 19 a 22: se o tipo de cliente for pessoa física, iniciamos aqui um bloco que solicitará ao usuário
os dados específicos. Assim, invocamos o construtor dessa classe específica para inicializar nosso ob-
jeto cliente (linha 20). Porém o compilador Java conhece a variável cliente como um objeto da classe
Cliente - foi assim que a declaramos na linha 14. Apesar de o que estamos fazendo aqui ser totalmente
válido – afinal, um objeto da classe PessoaFisica é também um objeto da classe Cliente (em virtude da
herança) -, precisamos “avisar” o compilador Java que nas linhas 21 e 22 utilizaremos cliente como um
objeto da classe PessoaFisica. Assim, usamos nessas linhas um outro recurso poderoso (e prático) de
Java, o casting, que permite que um objeto de um tipo (classe) seja interpretado como de outro tipo
(classe). Isso só será possível se houver uma relação de herança ligando esse objeto aos dois tipos,
como é o caso aqui. Você não pode, por exemplo, tentar usar casting em objetos que não possuem
relação “hereditária” um com o outro (por exemplo, um da classe Cliente com um de Conta). Nesse
caso, como sabemos que o cliente também é uma pessoa física, o comando - (PessoaFisica)cliente -
diz ao compilador que cliente também possui os métodos de um objeto PessoaFisica. Por essa razão,
podemos usar setNome e setCpf nele.
• Linha 23 a 26: aqui fazemos a verificação de se é um cliente do tipo pessoa jurídica. Caso seja, ini-
cializamos cliente de modo mais específico como um objeto PessoaJuridica. Em seguida, usamos
novamente o casting para poder chamar métodos específicos de PessoaJuridica em cliente (setRaza-
oSocial e setCnpj).
• Linhas 27 a 30: caso o usuário tenha digitado um valor inválido, que não indique nem cliente pessoa
física, nem pessoa jurídica, exibimos um aviso e encerramos o método main (consequentemente en-
cerrando o programa) com return.
• Linhas 32 e 33: já definimos em cliente, nas linhas anteriores, os valores específicos do seu tipo (por
exemplo, nome para pessoa física e razão social para pessoa jurídica). Faltam agora os dados genéri-
cos para qualquer tipo: cidade e estado. Definimos esses valores usando agora, diretamente, o objeto
cliente, sem casting e interpretado genericamente como do tipo Cliente.
• Linha 35: mostramos a “ficha cadastral” de cliente, usando o método listarDados(). Note que, durante
a execução, será exibida a versão de listarDados() específica para o tipo de cliente, inicializado como
pessoa física (linha 20) ou pessoa jurídica (linha 24). Aqui, estamos usando o recurso do polimorfismo,
que veremos em mais detalhes na próxima aula.

Antes de executar, você perceberá que surgiu também um erro na classe Conta. Trata-se do uso do getter
getNome() em listarDados. Como agora só teremos nome em cliente pessoa física (e não mais no cliente
genérico, como está declarado em Conta), precisaremos fazer um pequeno ajuste nessa classe. Modifique o
método listarDados em Conta seguindo a listagem no quadro 41.

66
Java JSE: Programação Básica

Quadro 41 - Nova versão do método listarDados na classe Conta

Explicando o código do quadro 41, temos:

• Na linha 22, usamos um comando especial de Java chamado instanceof. Ele serve para verificarmos se
um determinado objeto é uma instância de uma determinada classe. Por exemplo, cliente instanceof
PessoaFisica retorna true se o objeto cliente for dessa classe ou false se ele for uma instância de Pes-
soaJuridica (a outra possibilidade).
• Se ele for pessoa física, na linha 23, usamos novamente o casting para poder interpretar o cliente
genérico como PessoaFisica e usar seu método getNome. Caso seja pessoa jurídica, usamos também
casting na linha 25 para obter sua razão social.
• O valor obtido é usado, então, no retorno desse método para impressão dos dados da conta.

Acabamos usando aqui novamente o assunto da próxima aula: polimorfismo. Se você ainda não entendeu
completamente como ele funciona, não se preocupe. Vamos posteriormente implementá-lo em mais um local
importante.

Aula 7 – Polimorfismo

Conceito de polimorfismo

A etimologia da palavra polimorfismo já dá uma boa ideia do seu significado: originada do grego poli mor-
phos, significa literalmente muitas formas. Em programação OO, o termo é aplicado às várias maneiras com
que um mesmo método pode ser executado em diversas classes.

Nós já usamos o polimorfismo no exercício da aula anterior e vamos aplicá-lo novamente nesta. Veja a
nova versão do diagrama de classes do sistema bancário na figura 34.

67
Java JSE: Programação Básica

Figura 34 - Diagrama de classes do sistema bancário com polimorfismo.

Na figura, temos dois casos evidentes de polimorfismo: o método listarDados() e o método sacar().

O primeiro caso de polimorfismo já está implementado no código Java do nosso sistema: trata-se do
método listarDados(), existente em Cliente, PessoaJuridica e PessoaFisica. É um mesmo método que possui
três formas diferentes de executar - semelhantes, mas com conteúdo específico à classe no qual é definido.

Se você abrir o código da classe Cliente, verá que ela contém a versão básica de listarDados(), que traz
apenas uma string com o código, a cidade e o estado do cliente (veja no quadro 42).

Quadro 42 - Método listarDados() da classe Cliente

Como a classe PessoaFisica herda a classe Cliente, podemos concluir que um cliente PessoaFisica já re-
ceberá o método listarDados proveniente dela. Mas aí vem a pergunta: esse listarDados atende às necessi-
dades de PessoaFisica? Não, pois não mostra duas outras informações importantes sobre esse tipo: nome e
CPF. Agora, veja a nova implementação de listarDados() existente em PessoaFisica, exibida no quadro 43.

Quadro 43 - Implementação de listarDados() em PessoaFisica

Quando implementamos listarDados() em PessoaFisica, nós sobrescrevemos a versão original existente


em Cliente. Em Java, esse ato é conhecido como override. Isso significa que essa nova versão do quadro 43
é que será executada quando um objeto PessoaFisica executar o método listarDados.

68
Java JSE: Programação Básica

Mas isso não significa que perdemos o listarDados original. Veja no quadro 43 que, dentro de listarDa-
dos(), fazemos uma chamada ao existente em Cliente, nossa superclasse, usando o comando super. Assim,
podemos fazer com que essa nova versão funcione como um complemento da versão anterior.

Sobrecarga de métodos

A sobrecarga de métodos é um poderoso recurso existente na linguagem Java. Com ela, podemos definir
versões diferentes de um mesmo método (ou seja, com um mesmo nome) em uma mesma classe. Podemos
diferenciá-los por seus parâmetros.

Vamos supor que precisássemos ter em nossa classe Conta um método para depositar em dinheiro e outro
para depositar em cheque. A ideia inicial de quem não conhece a possibilidade da sobrecarga de métodos é
implementar dois métodos com nomes distintos:

depositarEmDinheiro(double valor);
depositarEmCheque(double valor, int numeroDoCheque);

Com essa abordagem, estamos dificultando um pouco mais a manutenção e a legibilidade do sistema.
Usando a sobrecarga de métodos, poderíamos criar os dois métodos da seguinte forma:

depositar(double valor);
depositar(double valor, int numeroDoCheque);

Quando o programador quiser invocar um depósi- Nós também já fizemos sobrecarga de métodos.
to em dinheiro, basta passar ao método depositar um Quando? Nos construtores das classes. Veja, no qua-
único parâmetro, o valor do depósito: dro 44, os dois construtores para Cliente que criamos.

depositar(5000); Quadro 44: Construtores sobrecar-


regados para a classe Cliente

Quando for feito em cheque, passamos dois parâ-


metros: o valor e o número do cheque.

depositar(2000, 73612);

O compilador Java saberá que, no primeiro caso,


estamos chamando a versão de depósito para dinhei-
ro, já que só um valor está sendo passado, e que,
no segundo, queremos a versão de depósito para
cheques, uma vez que dois parâmetros estão sendo
informados, um jeito muito mais fácil e sucinto.

69
Java JSE: Programação Básica

Quando instanciamos um objeto cliente, a quantidade de parâmetros passada ao construtor determina


qual versão será usada:

Cliente cli1 = new Cliente(); // cria um cliente usando o primeiro construtor

Cliente cli2 = new Cliente(“Campinas”, “São Paulo”); // cria usando a segunda versão

Polimorfismo na prática em Java: exercício prático guiado

O exercício desta aula consiste em criar as duas subclasses de Conta mostradas no diagrama da figura 34:
ContaCorrente e ContaPoupanca. O mais importante a ser implementado nelas é o conceito de polimorfismo
nas diferentes versões do método sacar.

No caso de ContaCorrente, o saque deverá considerar o limite na verificação do saldo disponível (ou seja,
o valor sacado deverá ser inferior ou igual ao saldo acrescido do limite). Para ContaPoupanca, deverá incluir
uma verificação: só será permitido se o dia atual for superior ao dia do aniversário da conta, para que não
haja prejuízo de rentabilidade (não é necessário verificar se é dia útil, como seria o caso em um sistema real).

Não é necessário implementar os métodos aplicarJuros() (de ContaCorrente) e aplicarRendimentos() (de


ContaPoupanca), mas, se você quiser tentar, vá em frente.

Não se esqueça de adaptar a classe Principal para utilizar as novas subclasses de Conta. Dê ao usuário a
possibilidade de escolher a criação de uma conta corrente ou de uma conta poupança.

Dica: para facilitar, crie o campo aniversario de ContaPoupanca como um int (ao invés de Date, como
indicado na figura 34) e armazene nele somente o dia do aniversário da conta poupança. Para obter o dia
atual em Java, use a classe Calendar com a seguinte linha de código:

int hoje = [Link]().get(Calendar.DAY_OF_MONTH);

Tente fazer essa prática sozinho e depois volte para conferir o resultado, mostrado a seguir no passo a
passo da solução.

1º passo: implementando a classe ContaCorrente

Vamos começar implementando a classe ContaCorrente. Clique sobre o pacote [Link] no Project
Explorer e, em seguida, no botão New Java Class da barra de ferramentas do Eclipse. Dê a essa classe o
nome ContaCorrente e escreva seu código seguindo a listagem do quadro 45. Não se esqueça de indicar que
ele herda a classe Conta, por meio do uso da palavra extends na sua declaração (linha 3).

70
Java JSE: Programação Básica

Quadro 45 - Código da classe ContaCorrente

71
Java JSE: Programação Básica

A explicação do código do quadro 45 é:

• Linhas 7 e 8: declaramos aqui os dois campos privados específicos dessa classe, o limite e a taxa de
juros, ambos do tipo double.
• Linhas 10 a 14: o primeiro construtor para ContaCorrente recebe um objeto Cliente apenas como pa-
râmetro, invoca o construtor equivalente na superclasse e atribui valores default para o limite e a taxa
de juros.
• Linhas 16 a 20: o segundo construtor permite a especificação de valores para o limite e a taxa de juros
da nova conta corrente.
• Linhas 22 a 25: nessas linhas, está declarada uma reimplementação do método getSaldoFormatado(),
que já existia na superclasse Conta. Na linha 22, inserimos uma annotation (anotação) Java, que fun-
ciona como uma espécie de “comentário inteligente” - nesse caso, a annotation @Override sinaliza ao
compilador que esse método está sobrescrevendo outro existente na superclasse. Apesar de não ser
obrigatório, o uso dela é conhecido como uma boa prática de programação Java. A nova versão de
getSaldoFormatado() foi escrita para trazer o valor do limite somado ao saldo, obtendo assim o real
saldo disponível (linha 24).
• Linhas 27 a 35: aqui está contida a reimplementação do método sacar(). O método sacar() de Conta-
Corrente deve considerar também o limite disponível no cheque especial, o que fazemos na linha 29.
• Linhas 37 a 48: a reimplementação de listarDados() contém o acréscimo do limite na exibição do saldo
disponível.
• Linhas 50 a 53: caso você tenha implementado o método aplicarJuros(), essa seria uma das maneiras
de escrevê-lo - subtraindo o valor dos juros do saldo apenas se este estiver negativo (sem considerar
o limite do cheque especial, nesse caso).

2º passo: implementando a classe ContaPoupanca

Vamos agora implementar a classe ContaPoupanca. Repita o procedimento de criação de uma classe,
dando a ela agora o nome ContaPoupanca (sem usar cedilha) e implementando seu código de acordo com a
listagem mostrada no quadro 46.

72
Java JSE: Programação Básica

Quadro 46 - Código da classe ContaPoupanca

A explicação do código do quadro 46 é:

• Linhas 7 e 8: declaramos os dois campos específicos de uma conta poupança - seu dia de aniversário
e sua taxa de rendimento.
• Linhas 10 a 20: nelas, estão contidos os dois construtores para ContaPoupanca, um com valores default
para os campos e o outro permitindo que eles possam ser passados como parâmetro.
• Linhas 22 a 31: a implementação do método sacar(), em ContaPoupanca, deverá verificar se o saque
estará sendo feito após o dia do aniversário, garantindo que os rendimentos tenham sido aplicados. Na
realidade, a implementação prática deveria considerar também o mês para ficar mais condizente com a
realidade, mas simplificamos nesse caso para podermos nos concentrar no uso do polimorfismo. Você
pode ajustar o código, caso julgue adequado, mas veja a nota importante abaixo.

73
Java JSE: Programação Básica

• Linhas 33 a 37: essa é uma das formas como você pode implementar o método aplicarRendimentos(),
creditando a aplicação da taxa de rendimentos sobre o saldo da conta.
• Importante: além da questão da consideração do mês na data de aniversário, em uma situação real,
precisaríamos também possuir um setter para o campo rendimento (setRendimento), uma vez que
essa taxa varia de mês a mês.

3º passo: usando as novas classes implementadas

Podemos agora implementar o uso das novas classes no sistema.

Vamos acrescentar à interface, no método main da classe Principal, a possibilidade de o usuário escolher
qual tipo de conta está criando. Adicione a ela o trecho de código indicado na listagem exibida no quadro
47. Ele dever ser inserido no local em que estava sendo instanciada a classe Conta, logo após a exibição dos
dados do Cliente.

Quadro 47 - Inclusão da escolha do tipo de conta na interface do sistema

O mais interessante é que não precisamos modificar mais nada. O uso do polimorfismo faz o resto.

Se for instanciada uma conta corrente, a exibição do saldo e o saque considerarão o limite disponível, o
que não ocorrerá no caso de uma conta poupança. Faça o teste e veja na prática.

Você verá que, no caso de ContaPoupanca, o saque não será permitido, pois usamos o construtor que
define o dia atual como aniversário. A condição implementada em sacar() impede que ele seja realizado, pois
verificará que o dia atual não é superior ao aniversário. Para que o saque em uma ContaPoupanca funcione,
modifique a linha relativa à criação do objeto dessa classe para usar o construtor com mais parâmetros e
passe um dia de aniversário inferior ao atual.

74
Java JSE: Programação Básica

Exercício do Módulo 3

Para praticar o conceito de herança, implemente no Eclipse um projeto que contenha as seguintes classes:

Neste exercício, você deverá fazer uso da herança na criação das classes, assim como do polimorfismo nos
métodos listarDados e calcularSalarioDoMes.

• Para Funcionario, o salário do mês será apenas seu salário base.


• Para Horista, o salário do mês será o total de horas trabalhadas multiplicadas pelo valor por hora.
• Já no caso do Vendedor, o salário será a soma do salário base com a comissão aplicada do total de
vendas realizado no mês.

75
Java JSE: Programação Básica

Módulo 4 – Arrays de objetos e coleções

Existe um momento em que um conjunto limitado de variáveis não é suficiente nem adequado para ar-
mazenar um grupo de informações. Nos casos em que precisamos ter em um sistema uma série de dados de
um determinado tipo, precisamos recorrer a estruturas que possibilitem o armazenamento de muitos valores
ao mesmo tempo. Você já conhece os vetores em Java usados para armazenar um conjunto de valores de
tipos primitivos, como int ou double. Mas e no caso de objetos? O que fazemos quando precisamos guardar,
por exemplo, um conjunto de objetos da classe Conta? Veremos neste último módulo como resolver essa
questão.

Aula 8 - Arrays e coleções em Java

Arrays de objetos e coleções

Um vetor em Java de valores de um tipo primitivo, como int, pode ser declarado, inicializado e utilizado
da forma indicada no quadro 48.

Quadro 48 - Uso de um vetor de inteiros

No exemplo, declaramos um vetor de seis valores int, chamado numerosDaSorte, atribuímos a cada posi-
ção um valor e exibimos seu conteúdo com um JOptionPane. Sabemos que, em Java, os índices de um vetor
são baseados em zero, o que indica que o primeiro elemento terá índice 0 e o último, n - 1 (sendo n a quan-
tidade de elementos do vetor). Também sabemos que vetores devem ser inicializados com a especificação da
quantidade de elementos que ele conterá para que a memória necessária seja alocada. Assim, não podemos
aumentar ou diminuir o tamanho de um vetor após ser inicializado.

O que você ainda não sabe é que podemos ter em Java vetores de objetos, assim como de tipos pri-
mitivos. Por exemplo, poderíamos declarar no nosso sistema bancário um vetor para Clientes e armazenar
objetos dessa classe em suas posições, como é mostrado no quadro 49.

76
Java JSE: Programação Básica

Quadro 49 - Declarando, inicializado e utilizando um vetor de objetos Cliente

O vetor clientes possui espaço para cinco objetos da classe Cliente. Perceba que, para cada objeto refe-
renciado por seu respectivo índice, podemos usar seus respectivos métodos individualmente. Essa é uma
abordagem interessante quando conhecemos previamente a quantidade de objetos que serão utilizados. Mas
e quando não sabemos?

Uma solução seria declarar um “megavetor”, com espaços além da capacidade máxima possível. Mas as-
sim ainda teríamos problemas, como o uso desnecessário de espaço de memória para os elementos que não
forem utilizados e ainda o risco de chegarmos ao limite declarado - mesmo que isso seja improvável, seria
um grande problema se acontecesse.

O ideal, nesses casos, é usar as classes de coleções da linguagem Java, que possibilitam que criemos
objetos containers de outros objetos - ou seja, vetores também, mas com tamanho dinâmico. Objetos de
coleção podem conter N objetos, sem precisar declarar a sua quantidade inicial de elementos e sem desper-
dício de espaço.

Existem várias classes de coleções de objetos em Java, mas vamos aprender apenas uma aqui, a mais
usada de todas: ArrayList. Na próxima seção, veremos como usá-la para implementar uma outra parte do
sistema bancário.

Uso de ArrayList e métodos para manipulação

Vamos praticar o uso das coleções de objetos em Java com ArrayList ao mesmo tempo em que apren-
demos como implementar mais uma parte do sistema bancário. Veja a nova versão do nosso diagrama de
classes na figura 35.

77
Java JSE: Programação Básica

Figura 35 - Diagrama de classes do sistema bancário.

A primeira diferença que você deve ter notado é a inclusão da classe Agencia, para representar uma
agência dentro da rede bancária. Agora veja a linha que liga Agencia a Conta e tente se lembrar do seu
significado.

O losango preenchido na ponta de Agencia indica que ela possui uma relação de composição com Conta,
ou seja, uma agência é composta por várias contas (o asterisco na ponta conectada à Conta indica essa mul-
tiplicidade). Relembrando, a composição indica que um todo (nesse caso, a Agencia) é composta por várias
partes (as Contas). A agência não pode existir sem contas, por isso temos nesse caso uma composição e
não uma agregação.

Como, em Java, vamos saber quais as contas que compõem uma agência? Uma maneira simples e eficien-
te é usar um ArrayList de objetos da classe Conta em Agencia.

Importante!

Seguindo as regras exatas da composição, não poderíamos permitir que uma agência existisse
sem contas. Porém não vamos implementar aqui esse tipo de controle e validação, visando
facilitar o entendimento do código do sistema.

Declaramos um ArrayList da seguinte forma:

List<Classe> lista = new ArrayList<>();

78
Java JSE: Programação Básica

Classe é o nome da classe de objetos que serão Uso de coleções no sistema bancário:
colocados na lista. Você deve importar a classe java. exercício prático guiado
[Link] e a interface [Link] no seu códi-
go. List é uma interface para a implementação de Para entender melhor como funciona um ArrayList,
listas em Java; ArrayList é uma classe que implemen- vamos implementar a classe Agencia e modificar
ta essa interface. Quando você for apresentado às a classe Principal para possibilitar a inclusão de
interfaces em Java, verá que elas são maneiras de múltiplas contas.
se estabelecer o que uma classe deverá ter em sua
implementação. Crie um nova classe Java dentro do pacote banco.
modelo, chamada Agencia, e escreva seu código de
Para armazenar um objeto no ArrayList, usamos acordo com a listagem do quadro 50.
seu método add:
Quadro 50 – Código-fonte da classe Agencia

Classe objeto = new Classe();


[Link](objeto);

Para remover um objeto em um ArrayList, é utili-


zado o método remove:

[Link](objeto);

Conseguimos saber quantos objetos existem no


ArrayList usando seu método size():

int totalDeObjetos = [Link]();

Podemos usar uma versão do comando for que


percorre automaticamente os objetos existentes em
um ArrayList, um de cada vez:

for (Classe objeto : lista) {


objeto.método();
}
O código do quadro 50 pode ser assim explicado:
Esse laço se repetirá pela quantidade de objetos
existentes em lista, percorrendo do primeiro ao úl- • Linhas 8 a 10: um objeto da classe Agencia
timo. Em cada passagem, o objeto representará o possuirá número, nome e uma lista de objetos
elemento atual. da classe Conta, denominada contas. Seguin-
do o princípio do encapsulamento, todos esses
campos são privados.

79
Java JSE: Programação Básica

• Linhas 12 a 16: a classe Agencia possui um único construtor, que recebe o número e o nome da
agência como parâmetros e inicializa a sua lista de contas vazia.
• Linhas 18 a 28: temos aqui um conjunto de getters para os campos. Repare que não definimos set-
ters; assim, os valores deles não poderão ser modificados após serem criados com o construtor. Apenas
no caso da lista de contas poderemos acrescentá-las ou removê-las, por meio dos métodos que serão
definidos.
• Linhas 30 a 36: definimos aqui um método para incluir um objeto à lista de contas e outro para re-
mover. Como são públicos, poderão ser utilizados para adicionarmos e excluirmos as contas de uma
agência.

Na tela Principal, vamos criar um objeto agencia e acrescentar um laço externo no qual o usuário poderá
optar entre incluir nova conta e cliente, listar as contas existentes ou sair do sistema. Modifique a sua classe
Principal, começando pelo trecho mostrado no quadro 51.

Quadro 51 – Classe Principal: linhas 1 a 28

Conforme mostra o quadro 51:

• Nesse início, declaramos e instanciamos agencia na linha 17. Também declaramos uma nova variável
para a escolha do usuário no menu principal (a string opcaoPrincipal, na linha 18).
• Começamos um laço na linha 20 que vai englobar todo o código até a linha 109 (mostrada adiante,
no quadro 54) e que se repetirá enquanto o usuário escolher as opções 1 ou 2 do menu criado entre
as linhas 21 e 26.
• Na linha 28, caso o usuário escolha a opção 1 do menu (criar cliente e conta), caímos em um bloco
que vai até a linha 95 (exibido adiante no quadro 54).

80
Java JSE: Programação Básica

O trecho exibido no quadro 52 é o mesmo que tínhamos anteriormente. A diferença fundamental é que
agora ele está contido dentro do laço principal iniciado na linha 20.

Quadro 52 – Classe Principal: linhas 29 a 56

O programa prossegue como mostra a listagem dos quadros 53 e 54.

Quadro 53 – Classe Principal: linhas 57 a 83

81
Java JSE: Programação Básica

Quadro 54 – Classe Principal: linhas 84 a 112

A listagem mostrada no quadro 53 possui um único, e importantíssimo, acréscimo: a linha 63. Nela,
adicionamos o objeto ContaCorrente ou ContaPoupanca criado à lista de contas da agência. Note que, sendo
uma lista de objetos da classe Conta, podemos acrescentar tanto uma conta corrente como uma conta
poupança, já que ambas são subclasses de Conta.

Se a opção do usuário no menu principal, mostrado no início do laço mais externo, for a segunda, ele
deseja visualizar uma listagem das contas cadastradas. São então executados os comandos contidos entre
as linhas 95 e 108.

Na linha 97, usamos o método size() do ArrayList contas para saber se existem contas incluídas nele. Caso
ainda não existam, avisamos o usuário do fato na linha 98.

Se contas possuir objetos, mostramos ao usuário os dados da agência e quantas contas ela possui
(linhas 100 a 102). Em seguida, usando a versão do laço for que conhecemos na seção anterior desta aula,
percorremos todas as contas existentes na lista, mostrando seus dados ao usuário (linhas 104 a 106).

82
Java JSE: Programação Básica

O que praticamos com este exemplo

Com essa última adição, implementamos boa parte do projeto de sistema bancário, incluindo os seguintes conceitos:
• Classes e objetos básicos, com seus atributos e ações.
• Encapsulamento, ocultando dados das classes que não devem ser acessados ou modificados e controlando
o uso deles, quando necessário, com getters e setters.
• Generalização e herança, na implementação de Conta, ContaCorrente e ContaPoupanca, assim como
Cliente, PessoaFisica e PessoaJuridica.
• Polimorfismo, na reescrita de métodos herdados, como listarDados() em Conta e ContaCorrente
• Sobrecarga de métodos, nos construtores de PessoaFisica, por exemplo
• Composição, usando ArrayList para fazer com que um objeto Agencia possua uma coleção de objetos
Conta.

Exercício do Módulo 4

Crie um aplicativo Java para armazenar uma lista de contatos.

Para isso, escreva o código necessário para uma classe denominada Contato, contendo campos para nome,
telefone e e-mail. Não se esqueça de criar um construtor, assim como getters e setters para os campos.

Na classe Principal, possibilite ao usuário cadastrar um conjunto de contatos e, antes de finalizar, mostre
os dados de todos a ele.

Para exibição dos dados de um contato, crie um método equivalente ao listarDados que usamos para
Clientes, mas chame-o agora de toString().

Fazendo a criação do toString() em Contatos, poderemos exibir os dados de um contato usando


simplesmente o objeto como parâmetro da impressão. Ao invés de usar:

[Link](null, [Link]() );

Usamos somente:

[Link](null, objetoContato);

83
Java JSE: Programação Básica

Respostas Comentadas dos Exercícios

Módulo 1

Dado Virtual

O primeiro cuidado que você deve ter é com relação à padronização do nome dos pacotes em Java
(sempre com todas as letras minúsculas) e das classes (primeira letra em maiúscula). A estrutura do seu
projeto Dado deve ter ficado da seguinte maneira:

Para realizar o sorteio de um número aleatório de 1 a 6, você pode utilizar a classe Random, que você
conheceu na disciplina de Lógica de Programação. Após instanciá-la em um objeto, basta chamar o método
nextInt() para sortear o número, que deverá ser exibido na janela do JOptionPane.

Esta é uma das possíveis soluções para este exercício:

84
Java JSE: Programação Básica

Comentários sobre o código:

• Linha 3: como vamos utilizar a classe Random, precisamos colocar um import para ela, de forma
que seja reconhecida por nossa classe Jogada.
• Linha 11: nesta linha instanciamos um objeto da classe Random, denominado gerador, e que
será usado para sorteio do número aleatório.
• Linha 12: fazemos aqui um “dois-em-um” sorteamos e mostramos o número usando apenas uma
linha de código. O método nextInt(valor), existente nos objetos da classe Random, sorteia um
número aleatório de 0 (inclusive) a valor - 1 (ou seja, o número anterior ao passado como parâmetro
ao comando nextInt, incluindo este como possibilidade).
• Isso significa que nextInt(6) poderia trazer como resultados possíveis os valores 0, 1, 2, 3, 4 e
5. Como não podemos ter 0 como resultado, e precisamos que o número seis também possa ser
dado como sorteado, simplesmente somamos 1 ao valor obtido. Assim, poderemos ter efetivamente
qualquer um dos seguintes resultados: 1, 2, 3, 4, 5 ou 6.
• Note que o resultado de nextInt é somado em 1, para que depois seja mostrado por showMes-
sageDialog. Isso significa que o método showMessageDialog pode ser usado para exibir direta-
mente valores inteiros, sem necessidade de conversão para String.

Potência

A implementação desse exercício é uma versão simplificada do que fizemos na Calculadora. Veja a listagem.

85
Java JSE: Programação Básica

Para poder realizar o que foi pedido no enunciado (fechar o programa caso seja fornecido valor inválido
para base ou expoente), agrupamos as duas entradas de dados e tentativa de conversão no mesmo bloco
try (linhas 13 a 16).

Caso ocorra um erro de conversão, a linha 18 no bloco catch mostra uma mensagem de erro, seguida,
na linha 19, por uma simples instrução return. Ela ocasiona o encerramento do método main, fazendo
com que o programa seja finalizado.

O método que faz o cálcula de potência é [Link](). Ele recebe dois parâmetros do tipo double:
primeiro a base e depois o expoente. Assim, fazemos o cálculo na linha 22 e mostramos o resultado usando
showMessageDialog(), na linha 23.

OBSERVAÇÃO: As linhas 23 e 24 correspondem a um único comando. Quebramos a linha no meio dele


para facilitar a visualização na listagem

Conversor Celsius para Fahrenheit

A implementação do conversor envolve basicamente a implementação correta da fórmula de conversão


fornecida no enuncida. Uma possível solução é apresentada na listagem a seguir.

Como você pode perceber pela listagem, a implementação é bastante simples e envolve basicamente
solicitar o valor em graus Celsius (linha 13), convertê-lo para double (linha 14) não se esquecendo
de tratar a possiblidade de erro de conversão (catch na linha 15) e, finalmente, na linha 20 calcular o
equivalente em Fahrenheit pela aplicaçãoda fórmula.

Repare que, como os graus e suas conversões podem ser obtidas em precisão decimal, declaramos as
variáveis auxiliares como double e usamos [Link] para converter o valor informado.

86
Java JSE: Programação Básica

Encerramos exibindo o resultado ao usuário na linha 21.

Adivinhe o número

87
Java JSE: Programação Básica

• Linhas 11 a 14: aqui declaramos as variáveis que vamos precisar no nosso programa. Temos três
variáveis int: uma para armazenar a quantidade de tentativas do usuário (inicializada com 0); uma
para o número informado pelo usuário (numeroPalpite); e outra para guardar o número sorteado
(numeroSorteado). Temos também uma String, chamada mensagem, que vai conter o texto das
mensagens que exibiremos.
• Linhas 16 e 17: nestas linhas instanciamos um objeto da classe Random, chamado gerador, que
será usado para o sorteio do número. Na linha 17, obtemos um valor aletório de 0 a 49 (passando
o valor 50 como parâmetro de [Link]) e somamos 1 a esse resultado, para assim obter
efetivamente um número de 1 a 50, que é guardado na variável numeroSorteado.
• Linha 19: armazenamos a primeira mensagem que mostraremos ao usuário na variável String com
este mesmo nome, e que declaramos na linha 14.
• Linha 22: não sabemos quantos palpites o usuário dará, mas ao menos um será feito (ou pelo me-
nos precisamos dar uma chance para ele digitar 0 e encerrar o programa). Por isso, um laço do tipo
do...while é ideal para este caso, já que garante que pelo menos uma janela de entrada de dados
será apresentada ao usuário. Repare que este laço se encerra na linha 37 e que sua condição de
continuidade é que o palpite seja diferente de zero e também (por isso o && - operador booleano
AND) diferente do número sorteado. Essa condição será quebrada quando o usuário digitar 0 ou
acertar o número.
• Linha 23: exibimos a mensagem ao usuário e armazenamos o valor informado por ele em nume-
roString.
• Linha 24: iniciamos um bloco try...catch para converter o valor informado como String para int.
• Linha 25: fazemos a conversão de String para int usando o método parseInt da classe Integer.
No caso de falha na conversão (uma exceção), o fluxo de execução do programa será desviado
para a cláusula catch, na linha 34.
• Linhas 26 a 33: o primeiro if é usado para confirmar se o usuário deu um palpite ou digitou zero
para finalizar. Dentro dele, caso o usuário tenha realmente dado um palpite, temos um outro if para
testar se o número sorteado é inferior (linha 27) ou superior (linha 29) ao sorteado, atribuindo à
String mensagem a informação que será passada. Na linha 32, incrementamos o contador de
tentativas.
• Linhas 34 a 36: este bloco catch exibe uma mensagem de aviso caso tenha ocorrido um erro de
conversão (reconhecido como uma exeção denominada NumberFormatException em Java) na
linha 25.
• Linha 37: como mencionado anteriormente, o laço do...while será quebrado quando o usuário
acertar digitar 0 ou acertar o número.
• Linha 39: após sair do laço, precisamos avisar o usuário sobre o que aconteceu. Das duas, uma:
ou ele desistiu, ou acertou o número. Em ambos, precisamos mostrar também quantas tentativas
foram feitas. Nesta linha, declaramos uma variável String chamada resultado. Usaremos ela pos-
teriormente para montar a mensagem que será passada ao usuário. Sua única função é conter a
razão do término do laço: se o usuário acertou o número, armazenamos nela o texto “acertou”; se
o usuário desistiu, guardamos nela a mensagem “desistiu de acertar “. Poderíamos fazer isso com
um if...else simples, mas também podemos simplificar ainda mais usando o operador ternário,
que conhecemos na seção 3.2, na Aula 3. Ficou curtinho, não é mesmo? E funciona mesmo!

88
Java JSE: Programação Básica

• Linha 42: encerramos o programa mostrando ao usuário a mensagem final. Note que, usando a
variável resultado criada na linha 39 e o operador de concatenação de Strings (+), a mensagem
será criada adequadamente tanto no caso acerto quanto no de desistência.

Histograma

Veja na listagem a seguir e nos comentários uma das soluções para o exercício do Histograma.

Se você realizou a contagem de ocorrências de sorteio para cada número em variáveis individuais (usando,
por exemplo, contador1, contador2, ..., contador10), repare na listagem como o uso de um vetor torna
o código mais compacto e eficiente.

89
Java JSE: Programação Básica

• Linha 10: começamos declarando e instanciando nosso objeto gerador de números aleatórios,
proveniente da classe Random. Neste caso, ele se chamará random (em letras minúsculas).
• Linha 11: declaramos e incializamos um vetor de inteiros com dez posições, chamado histogra-
ma. Na linguagem Java os índices de um vetor começam por zero. Dessa forma, seu primeiro ele-
mento será histograma[0] e seu último (o décimo) será histograma[9]. Em Java, os elementos
de vetores int são inicializados contendo 0.
• Linha 12: como a String com o histrograma será gerada por meio de várias concetenações, o ideal
é utilizar para tanto um objeto da classe StringBuilder. Declaramos aqui o objeto construtorDeS-
tring para essa finalidade.
• Linha 14: concatenamos ao construtorDeString, usando o método append, o título informativo
“HISTOGRAMA”, junto de uma quebra de linha (“\n”).
• Linhas 16 a 18: por incrível que pareça, dentro deste pequeno laço fazemos o sorteio dos 100
números de 1 a 10 e também guardamos no vetor histograma a quantidade sorteada de cada
um. Como? Primeiramente, note na linha 16 que nosso laço é um for com um contador i, que inicia
em 0 vai até 99 (obedecendo a condição i < 100). Isso nos garante cem sorteios. O que precisa-
mos é incrementar em uma unidade a posição do vetor histograma relativa ao número sorteado.
É justamente isso que fazemos: veja que realizamos um pós-incremento (operador ++) no vetor
histograma, exatamente no índice correspondente ao número sorteado. E para o código não ficar
redundante, é o próprio sorteio ([Link](10)) que serve como índice para a posição ade-
quada no vetor a ser incrementada. Não entendeu? Vamos usar um exemplo passo-a-passo:
o A linha diz: histograma[[Link](10)]++;
o A primeira coisa que acontence na linha é a execução do comando mais interno, ou seja, a
chamada ao método nextInt() dentro dos colchetes do índice do vetor. Passamos como pa-
râmetro o número 10 a ele, o que significa o retorno de um valor de 0 a 9. “Mas não tinha
que ser de 1 a 10?”, você pergunta. Sim, mas você deve concordar que 0 a 9 correspondem
efetivamente a 10 números possíveis: podemos interpretar o 0 como 1 e o 9 como 10. Logi-
camente, o resultado é o mesmo, e dessa forma também facilitamos o acesso ao respectivo
índice no vetor;
o Suponha que [Link](10) sorteie o número 5. Isso implica que a linha 17 equiva-
lerá a: histograma[5]++;
o Concluímos que será incrementado o valor existente na posição 5 do vetor, que para nós equi-
vale ao número 6 (assim como o elemento 0 equivale ao 1, e o 9 ao 10).
o Essa abordagem evita o (desnecessário) uso de if ou switch...case para determinar qual
posição do vetor será incrementada, deixando o código mais elegante e eficiente.
• Linhas 20 a 25: feito os cem sorteios, temos no nosso vetor histograma a quantidade de vezes
que cada número foi sorteado. Esse laço é usado justamente para montar a String que funcionará
como nosso “gráfico em modo texto”. Começamos com um laço que vai de 0 a 9, para que possa-
mos percorrer todo o vetor histograma. Na linha 21, concatenamos ao construtorDeString o
número da posição atual do contador somado de 1, seguido de “: “. Isso faz com que, no primeiro
elemento do vetor seja impresso “1: “ (nós estamos guardando os números como 0 a 9, mas o usu-
ário espera ver o resultado como 1 a 10). Precisamos agora imprimir uma quantidade de cerquilhas
relativas ao número de vezes que 1 (0, nos “bastidores” do programa) foi sorteado. Isso está guar-
dado em histograma[0]. Na linha 22, usamos um segundo laço for, que utilizará um contador do
tipo int chamado j, o qual vai de 0 até o valor anterior ao existente em histograma[i] (condição j

90
Java JSE: Programação Básica

< histograma[i]). Assim, se na posição 0 do vetor histograma estiver o número 5 (indicando que
o primeiro número foi sorteado cinco vezes), nosso laço interno repetirá também cinco vezes (de
0 a 4). Dentro dele, na linha 23, concatenamos uma cerquilha à construtorDeString para cada
iteração. Nesse exemplo, então, serão concatenadas cinco cerquilhas. Quando todas as cerquilhas
necessárias forem impressas, o laço interno termina. Antes de passar à próxima posição do vetor,
adicionamos à construtorDeString uma quebra de linha, para que possamos obter a visualização
adequada do histograma. Assim acontecerá sucessivamente, até terminarmos de percorrer histo-
grama.
• Linha 27: finalizado o laço principal, nosso “histograma TXT” está pronto. Mostramos ele ao usuário
com [Link], finalizando nosso programa.

Módulo 2

Forca

Há várias formas de se implementar corretamente o exercício da Forca. A maneira apresentada aqui é


apenas uma delas, e leva em consideração a aplicação de boas práticas de programação Java que você está
conhecendo no curso, como o encapsulamento.

Vamos começar com o código para a classe Forca. da como privada, pois não deverá ser aces-
sada externamente à classe.
• Linha 10: declaramos um novo vetor de
Strings, chamado forcas, com sete po-
sições. Ele será usado para armazenar os
“desenhos” ASCII para os sete estágios de
“enforcamento”.
• Linhas 12 e 13: na linha 12 é declarada
uma variável privada int para a contagem
de erros. Já na linha 13, declaramos uma
variável contendo o índice da palavra sorte-
ada para o jogo, dentro do vetor palavras
declarado na linha 7.
• Linha 14: à medida que o usuário vai fa-
zendo seus acertos, exibiremos a ele uma
versão parcial da palavra sorteada, a pala-
vraExibida. Esta palavra começará apenas
com traços no lugar das letras, que serão
• Linha 7: começamos declarando um vetor trocadas a medida que usuário acerta uma
de Strings chamado palavras. Nele, colo- letra existente. Como teremos que mani-
camos um conjunto de palavras que pode- pular o seu conteúdo, usamos aqui classe
rão ser usadas no jogo. Seguindo o princípio StringBuilder ao invés de simplesmente
do encapsulamento, esta variável é declara- usar uma String padrão, cujo conteúdo é
imutável.

91
Java JSE: Programação Básica

• Linha 16 e 17: iniciamos aqui o construtor No trecho que compreende as linhas entre 28 a
para a classe Forca e inicializamos a conta- 55, temos mais quatro estágios do “enforcamento”,
gem de erros com zero. cada um na sua respectiva posição do vetor forcas.
• Linhas 18 e 19: instanciamos um objeto
da classe Random e usamos o mesmo para Veja um detalhe importante na linha 53: como
sortear um número entre zero e o tamanho colocamos uma barra invertida ( \ ) para representar
do vetor de palavras. Guardamos o resulta- o braço esquerdo do enforcado, precisamos repeti-la
do do sorteio em indiceDaPalavraSorte- para que o Java não a interprete como o início de um
ada, para que saibamos qual será a palavra caractere de controle (como o \n, por exemplo). Por
que o jogador deverá adivinhar. ter adicionado a segunda barra, também colocamos
• Linha 20: no início do jogo, a palavra esta- um espaço a mais nesta linha, de forma que ela fique
rá totalmente escondida do usuário – serão com tamanho proporcional às demais.
exibidos apenas traços no lugar das letras
em palavraExibida. Fazemos isso crian-
do uma cópia da palavra sorteada, onde to-
dos seus caracteres são trocados por traços
usando o método replace das Strings.

• Linhas 22 a 27: guardamos na primeira


posição do vetor forcas o “desenho”, em
formato de caracteres ASCII, para a forca
vazia. Para que ele seja impresso correta-
mente, note que ao final de cada linha colo-
camos uma quebra (\n).

Nas linhas 57 a 69, temos a definição dos dois


últimos estágios da forca. Na linha 71, fechamos o
construtor para Forca, iniciado na linha 16.

Para poder exibir o estágio atual de enforcamento


ao jogador, criamos um getter nas linhas 73 a
75. Ele retorna a posição do vetor forcas - que
é inicializado no construtor da classe - na posição
relativa à quantidade de erros.

Nas linhas 77 a 79, criamos um getter para exibir


ao usuário aquilo que ele já descobriu da palavra
secreta (e que está em palavraExibida).

92
Java JSE: Programação Básica

Nas linhas 81 a 91, temos o método vital para o jogo: testarLetra. Sua função é receber como
parâmetro a letra que o usuário “chutou”, verificar se a mesma existe na palavra secreta e, em caso positivo,
atualizar a palavra exibida para mostrar onde a letra informada se encontra.

Primeiro, na linha 82, usamos o método contains() da String para verificar se a palavra sorteada
possui a letra informada.

Em caso positivo, o bloco entre as linhas 83 e 87 é executado. Dentro dele, percorremos cada um dos
caracteres existentes na palavra sorteada, comparando-os com o que foi digitado pelo usuário. Se coincidir,
substituímos na palavraExibida o traço pelo caractere, na sua posição correspondente (linha 85), usando
o método replace() existente em objetos do tipo StringBuilder.

No caso da letra informada não existir na palavra sorteada, incrementamos o contador de erros na linha
89.

Nas linhas 93 a 95, temos um getter para retornar a quantidade de erros do usuário. Ele será necessário
para futuramente testarmos o fim do jogo na classe Principal.

Caso o usuário não acerte a palavra, o getter definido entre as linhas 97 e 99 será usado na classe
Principal para exibir a palavra secreta ao jogador.

Você deve ter notado que nossa implementação da Forca traz apenas os getters necessários, e nenhum
setter. Os valores das variáveis internas são modificados pelo método testarLetra. Dessa forma, cumprimos
corretamente a prática do encapsulamento, escondendo do usuário da classe aquilo que não precisará ser
utilizado.

93
Java JSE: Programação Básica

Podemos passar agora à implementação da interface do jogo, na classe Principal.

Começamos declarando na linha 12 um objeto JTextArea, chamado textoForca. Trata-se de uma “área
de texto” usada no framework de janelas do Java, o Swing. Como dissemos na apresentação do exercício,
vamos usá-lo para que o “desenho de traços” da forca seja mostrado corretamente ao usuário, usando uma
fonte de largura fixa (e que é definida na linha 13).

Na linha 15, declaramos e inicializamos uma instância da classe Forca, no objeto forca. O laço iniciado
na linha 17, e que vai até a linha 25, controla a execução do jogo. Você pode perceber pela condição de
continuidade do laço, na linha 25, que o mesmo será encerrado somente se a quantidade de erros do usuário
chegar a 6 (neste caso, o jogador não conseguiu acertar a letra) ou se a palavra exibida não contiver mais
traços (o que ocorrerá quando o jogador acertar a palavra).

Dentro do laço, repetimos a exibição do estágio de enforcamento e da palavra sendo adivinhada (linha
18), assim como fazemos a solicitação de uma letra. A letra informada pelo usuário é então testada pelo
método testarLetra, no objeto forca (linha 24). Fazemos também uma pequena validação: caso o usuário
não forneça uma letra, consideramos que uma cerquilha foi digitada, resultando em erro na adivinhação e
aumentando o “enforcamento”.

94
Java JSE: Programação Básica

O encerramento do laço implica em vitória ou derrota do jogador. Para exibir uma mensagem adequada a
ele, testamos a quantidade de erros na linha 29 e criamos uma mensagem correspondente para cada caso.

Finalmente, nas linhas 35 e 36, mostramos o resultado, junto da palavra secreta e estágio final da forca.

Módulo 3

Complementando o sistema bancário

Começamos implementando a classe Conta, seguindo as especificações do exercício:

95
Java JSE: Programação Básica

Você pode notar a semelhança entre a implementação do número sequencial da conta e do código do
Cliente - o conceito fundamental é o mesmo: o uso de um campo estático.

Um grande diferencial neste código está no uso de um campo referenciando um objeto de outra classe. Essa
é uma das maneiras que implementamos associações entre classes em Java. O campo cliente, declarado na
linha 8, receberá um objeto Cliente, sendo usado para identificar o correntista.

Note no método listarDados (linha 20 a 24) que retornamos o nome do correntista usando o campo
cliente e, dentro deste, seu campo nome. Isso é perfeitamente possível, em virtude do campo nome possuir
a visibilidade public dentro da classe Cliente.

Uma outra novidade é o uso da classe DecimalFormat do Java, na linha 23. Usamos ela para queo valor
double do saldo seja exibido em formato financeiro, usando as configurações regionais do sistema.

Agora, para testar o uso da classe, você pode comentar as linhas existentes no método main da classe
prinicipal (para poder recuperá-las depois) e acrescentar as seguintes:

Começamos instanciando um objeto cliente e definindo para seus campos os valores de retorno obtidos
com as janelas de entrada.

Em seguida, conforme o enunciado do exercício, mostramos a “ficha do cliente”, com uma chamada ao
método listarDados().

96
Java JSE: Programação Básica

Instanciamos então um objeto da classe Conta, passando ao seu construtor o objeto cliente referente
ao correntista.

Por fim, mostramos os dados da conta, usando o método [Link]().

Funcionarios

A implementação deste exercício consiste na escrita da superclasse Funcionario e suas subclasses Horista
e Vendedor, utilizando o conceito do polimorfismo ao escrever seus métodos calcularSalarioDoMes() e
listarDados().

A classe Funcionario poderia ser implementada como a listagem a seguir.

97
Java JSE: Programação Básica

Uma vez que a classe Funcionario possuirá duas subclasses, declaramos seus campos nome, setor e
salarioBase como protected, para que os mesmos possam ser acessíveis pelas subclasses (linhas 5 a 7).

Nas linhas 9 a 14 temos um construtor para Funcionario que recebe como parâmetros os atributos
básicos da classe e os armazena nos respectivos campos. Os getters e setters para os campos da classe são
definidos nas linhas 16 a 38.

O método calcularSalarioDoMes(), escrito entre as linhas 40 e 42, é uma versão simplificada para
o salario do funcionário – ele apenas retorna seu salário base. Nas subclasses Horista e Vendedor,
reescreveremos este método para considerar as diferenças do salário destes dois tipos especializados de
Funcionario.

A seguir, a implementação da classe Horista, subclasse de Funcionario.

A classe Horista herda a classe Funcionario, como podemos ver pelo uso de extends, na linha 3.
Dessa forma, “recebe automaticamente” seus campos e métodos.

98
Java JSE: Programação Básica

Complementando a classe, acrescentamos nas linhas 5 e 6 dois campos específicos para um funcionario
Horista, horasTrabalhadasNoMes e valorPorHora.

Nas linhas 8 a 13, temos o método construtor para um Horista. Ele recebe todos os parâmetros
necessário (inclusive aqueles recebidos de Funcionario). Para definição dos atributos genéricos (nome,
setor e salário-base), invocamos o construtor da superclasse, usando super(). Já a definição dos atributos
específicos (horasTrabalhadasNoMes e valorHora) é feita diretamente nos campos locais da classe.

Entre as linhas 15 e 25 temos alguns dos getters e setters para os campos locais de Horista.

Nas linhas 27 a 29 é definido o setter para o campo valorPorHora.

A primeira “novidade” desta classe é apresentada nas linhas 31 a 34, onde reescrevemos (ou como
preferem alguns, sobrescrevemos) o método calcularSalarioDoMes, herdado de Funcionario. A anotação
@Override, existente na linha 31, indica ao compilador Java que o método a seguir trata-se de uma
reimplementação. Dentro do método, calculamos e retornamos o salário do funcionário Horista, obtido por
meio da multiplicação da quantidade de horas trabalhadas pelo valor da hora.

A classe é encerrada com outra reimplementação: a do método listarDados (linhas 46 a 41). Basicamente,
ele agrega ao retorno do método existente na superclasses as informações relativas ao Horista.

99
Java JSE: Programação Básica

Passamos agora à classe Vendedor, uma outra variação de Funcionario.

A primeira parte de Vendedor segue os mesmos conceitos usados em Horista: herança de Funcionario,
campos privados locais, seus respectivos getters e setters e um construtor.

A implementação de calcularSalarioDoMes de Vendedor, definida nas linhas 31 a 34, retorna o


salario usando uma regra específica para vendedores: o salário total é composto pelo salário base acrescido
da comissão em função das vendas realizadas.

Nas linhas 36 a 41 temos a reimplementação de listarDados. Nela, agregamos ao retorno da versão


existente na superclasse (Funcionario) os dados relativos ao Vendedor.

100
Java JSE: Programação Básica

Veja na próxima listagem um exemplo de utilização destas classes.

Reapre que no método main da classe Principal declaramos três objetos da classe Funcionario
(generico, horista e vendedor), mas para cada um deles usamos um construtor diferente!

Todos são funcionários, mas apenas generico é um Funcionario comum, já que instanciamos este
objeto usando o construtor da superclasse; horista, apesar de declarado como Funcionario, é instanciado
usando o construtor da classe Horista; e para vendedor, também declarado como Funcionario, usamos o
construtor de Vendedor. Como um Horista e um Vendedor também são Funcionários, as declarações e
inicializações realizadas nas linhas 9 a 11 são perfeitamente válidas!

Agora repare no que será exibido nos JOptionPane existentes nas linhas 13 a 15. Apesar de declarados
como objetos da classe Funcionario, as versões de listarDados e calcularSalarioDoMes para horista e
vendedor serão aquelas das classes pelas quais foram instanciados, Horista e Vendedor!

Essa é mais uma amostra da flexibilidade que temos em uma linguagem orientada a objetos como Java,
graças à herança e ao polimorfismo.

Módulo 4

Contatos

Este exercício serve como prática do uso de coleções de objetos em Java, por meio da classe ArrayList.
Começamos criando um classe Contato, contendo os dados que serão guardados sobre uma pessoa na
“agenda virtual” do usuário.

101
Java JSE: Programação Básica

Temos neste trecho a declaração dos campos privados nome, telefone e email (linhas 5 a 7), a
definição do construtor (linhas 9 a 13) e de getters e setters para nome e telefone, seguindo os padrões
do encapsulamento.

Neste último trecho, são criados os getters e setters restantes (entre as linhas 27 e 37) e uma novidade:
o método toString (linhas 39 a 44).

102
Java JSE: Programação Básica

O método toString é padronizado em Java, e serve para trazer uma “representação String” do que o
objeto contém.

Toda classe criada em Java descende de uma superclasse comum, denominada Object. Nesta classe, há
uma implementação padrão de toString, que traz apenas um identificador para o objeto. Se o desenvolvedor
desejar, pode reimplementar toString em sua classe, retornando uma String com informações sobre o
objeto da maneira que achar mais conveniente. Fazer esse procedimento tem uma grande vantagem: quando
passarmos um objeto com uma implementação de toString como parâmetro do tipo String de algum
método (como por exemplo o método de impressão no terminal [Link] ou um JOptionPane.
showMessageDialog), toString será invocado automaticamente, retornando o valor definido na sua
implementação.

Vamos ver na prática o resultado de usar toString na utilização de Contato, como a exemplificada na
classe Principal a seguir.

Na linha 11, declaramos um ArrayList de objetos da classe Contato, denominado contatos, e


inicializamos o mesmo usando seu construtor padrão.

Após solicitar os dados básicos de um contato nas linhas 15 a 17, instanciamos um objeto Contato
na linha 18 e adicionamos o mesmo ao ArrayList contatos, na linha 19. Tudo isso será feito dentro de

103
Java JSE: Programação Básica

um laço do...while (linhas 14 a 22), que se repetirá enquanto o usuário optar em continuar adicionando
contatos. Cada novo objeto contato será guardado dentro do ArrayList contatos por meio do método add.

Finalizado o laço, mostraremos os dados de todos os contatos criados ao usuário. Para isso, usaremos um
“for especial” existente em Java, que percorre automaticamente elementos em uma lista ou vetor (linhas
24 a 26).

Na declaração do for (linha 24), especificamos que vamos percorrer o ArrayList contatos, e que cada
um de seus elementos (do primeiro ao último) será referenciado pela variável umContato – um por vez,
para cada iteração do laço.

Dentro do laço, usamos o [Link] para exibir os dados do contato. Repare


no segundo parâmetro deste método – ao invés de usar uma String ou um método que retorne uma
String (como fizemos até agora), colocamos diretamente o objeto umContato! Como definimos na classe
Contato um método toString, e como este segundo parâmetro “pede uma String”, o toString do objeto
será invocado automaticamente. Assim, conseguimos o mesmo efeito que antes tínhamos com o método
listarDados!

Como prática adicional, procure agora abrir os exercícios anteriores e trocar o listarDados ou por um
toString, deixando seu código ainda mais “enxuto”!

104
Java JSE: Programação Básica

Considerações Finais

Chegamos ao final de mais uma etapa deste curso. Parabéns!

Nesta disciplina, pudemos “entrar de cabeça na linguagem Java”, conhecendo inclusive o ambiente de
desenvolvimento integrado mais usado no mundo junto com ela: o Eclipse.

Você pôde descobrir como fazer o download, instalar e criar projetos Java no Eclipse, bem como localizar
e corrigir erros, além de testar seus aplicativos.

Fizemos uma revisão rápida de estruturas de controle e decisão, levando em conta as peculiaridades da
linguagem Java e usando uma abordagem de entrada e saída de dados mais visual.

O ponto principal da linguagem Java, uso de classes e objetos, foi explorado implementando classes do
sistema bancário. Com essa abordagem, você pôde ficar conhecendo mais sobre as classes já existentes na
API básica da linguagem Java (como String, Random, Integer, Double e StringBuilder), assim como
pôde descobrir como criar suas próprias classes. É assim que seus programas orientados a objetos serão
compostos: uma mescla de classes preexistentes com aquelas que você mesmo cria, com base na engenharia
de requisitos e a consequente modelagem do sistema usando UML.

Futuramente, você conhecerá outros frameworks e tecnologias utilizados para criação dos mais diversos
tipos de aplicativos em Java. Em todos eles, você perceberá que as classes essenciais do Java SE e os conceitos
fundamentais de engenharia de software, orientação a objetos e UML serão utilizados intensamente.

O campo de desenvolvimento Java é imenso e cheio de empolgantes oportunidades - não deixe de


aproveitá-las!

Prof. Querino

105
Java JSE: Programação Básica

Referências Bibliográficas

ARNOLD, K.; GOSLING, J.; HOLMES, D. A linguagem de programação Java. Porto Alegre: Bookman,
2007.

BARNES, D. J.; KÖLLING, M. Programação orientada a objetos com Java. São Paulo: Pearson
Prentice-Hall, 2004.

BLOCH, J. Effective Java. Upper Saddle River: Addison-Wesley, 2012.

BOOCH, G.; RUMBAUGH, J.; JACOBSON, I. UML: guia do usuário. Rio de Janeiro: Elsevier, 2012.

DEITEL, H.; DEITEL, P. Java: como programar. São Paulo: Prentice-Hall, 2010.

ECLIPSE FOUNDATION. Eclipse. [website]. 2014. Disponível em: [Link] acesso em:
[Link].2014.

FLANAGAN, D. Java: o guia essencial. Porto Alegre: Bookman, 2006.

GOSLING, J.; MCGILTON, H. The Java language environment. 1997. Disponível em: [Link]
[Link]/technetwork/java/[Link], acesso em: [Link].2014.

HIRONDELLE SYSTEMS. Collected Java practices. 2014. Disponível em: [Link]


com/, acesso em: [Link].2014.

ORACLE. Java 7 API. 2013. Disponível em: [Link] acesso em:


[Link].2014.

________. Java tutorial. 2014. Disponível em: [Link] acesso em:


[Link].2014.

PRESSMAN, R. S. Engenharia de software. São Paulo: McGraw-Hill, 2010.

QUERINO FILHO, L. C. Desenvolvendo seu primeiro aplicativo Android. São Paulo: Novatec, 2013.

SOMMERVILLE, I. Engenharia de software. São Paulo: Addison-Wesley, 2007.

106

Você também pode gostar