Java JSE Programação Básica
Java JSE Programação Básica
1
Java JSE: Programação Básica
Apresentação 4
2
Java JSE: Programação Básica
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ê.
Então vamos lá! Prepare-se para mergulhar de cabeça na linguagem de programação orientada a objetos
mais usada no mundo.
4
Java JSE: Programação Básica
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.
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):
6
Java JSE: Programação Básica
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.
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).
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.
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:
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.
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.
9
Java JSE: Programação Básica
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.
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).
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.
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.
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
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.
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
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
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).
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).
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.
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.
Veja o novo arquivo criado no seu projeto, o [Link]. Ele será aberto na tela central do Eclipse (veja
figura 17).
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.
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.
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.
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.
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
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).
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
24
Java JSE: Programação Básica
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.
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.
25
Java JSE: Programação Básica
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.
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.
[Link](5);
No exemplo do quadro 7, como o valor passado possui ponto decimal, será considerado como um 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.
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.
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.
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:
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.
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
Posteriormente, para obter do objeto StringBuilder uma string tradicional, basta usar o método toString().
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:
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:
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.
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
Conseguiremos realizar facilmente esses passos usando os conceitos aprendidos até agora. Um forma de
implementar esse exercício é mostrada no quadro 13.
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
• 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.
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
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.
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.
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.
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:
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
Siga os passos:
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.
39
Java JSE: Programação Básica
40
Java JSE: Programação Básica
Ao executar, você deverá obter uma janela semelhante à mostrada na figura 30.
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:
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
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.
Agora podemos usar qualquer um dos dois construtores. Se instanciarmos um objeto usando o sem parâ-
metros, devemos fazer desta forma:
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:
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
44
Java JSE: Programação Básica
• 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.
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!
• 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:
Aula 5 - 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.
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.
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.
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
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:
É uma convenção de Java que métodos getter devem ter seu nome definido da seguinte forma:
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.
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
Assim como nos getters, é uma convenção de Java que métodos setter devem ter seu nome definido da seguinte
forma:
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.
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.
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.
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 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
Agora, precisamos fazer algumas modificações no nosso sistema bancário, por três motivos:
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.
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.
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ê.
Vamos agora passar à classe Conta. Primeiro mudaremos os modificados de visibilidade dos campos,
como indicado no quadro 33.
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
• 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.
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
• 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.
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
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.
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.
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
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.
Agora, implemente o restante do código para PessoaFisica seguindo a listagem do quadro 38.
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.
63
Java JSE: Programação Básica
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
• 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
• 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
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).
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.
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(2000, 73612);
69
Java JSE: Programação Básica
Cliente cli2 = new Cliente(“Campinas”, “São Paulo”); // cria usando a segunda versão
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 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:
Tente fazer essa prática sozinho e depois volte para conferir o resultado, mostrado a seguir no passo a
passo da solução.
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
71
Java JSE: Programação Básica
• 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).
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
• 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.
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.
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.
75
Java JSE: Programação Básica
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.
Um vetor em Java de valores de um tipo primitivo, como int, pode ser declarado, inicializado e utilizado
da forma indicada no quadro 48.
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
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.
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
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.
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
[Link](objeto);
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.
• 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.
81
Java JSE: Programação Básica
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
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
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().
[Link](null, [Link]() );
Usamos somente:
[Link](null, objetoContato);
83
Java JSE: Programação Básica
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.
84
Java JSE: Programação Básica
• 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.
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
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
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.
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
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
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.
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().
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 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.
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
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.
100
Java JSE: Programação Básica
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.
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.
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
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.
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.
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.
GOSLING, J.; MCGILTON, H. The Java language environment. 1997. Disponível em: [Link]
[Link]/technetwork/java/[Link], acesso em: [Link].2014.
QUERINO FILHO, L. C. Desenvolvendo seu primeiro aplicativo Android. São Paulo: Novatec, 2013.
106