História do Java Introdução a tecnologia de Objetos e UML

Propaganda
História do Java
Em 1991, na Sun Microsystems, foi iniciado o Green Project, o berço
do Java uma linguagem de programação orientada a objetos. Os mentores dos
projetos eram Patrick Naughton, Mike Sheridan, e James Gosling. O Objetivo do
projeto não era a criação de uma nova linguagem de programação, mas antecipar
e planejar a “próxima onda” do mundo digital. Eles acreditavam que em algum
tempo haveria uma convergência dos computadores com os equipamentos
eletrodomésticos comumente usados pelas pessoas no seu dia-a-dia.
Para provar a viabilidade da idéia, 13 pessoas trabalharam arduamente
durante 18 meses. No verão de1992 eles emergiram de um escritório de Sand Hill
Road no Menlo Park com sua demonstração funcional da idéia inicial. O protótipo
se chamava *7 (leia-se “StarSeven”), um controle com uma interface gráfica
Touchscreen. Para o *7 foi criado um mascote, hoje amplamente conhecido no
mundo Java, o Duke. O trabalho do Duke no *7 era ser um guia virtual ajudando e
ensinando o usuário a utilizar o equipamento. O *7 tinha a habilidade de controlar
diversos dispositivos de e aplicações. James Gosling especificou uma nova
linguagem de programação para o *7. Gosling decidiu batiza-la de “Oak”, que
quer dizer carvalho, uma árvore que ele podia observar quando olhava pela sua
janela.
Introdução a tecnologia de Objetos e UML
Para iniciar o assunto sobre orientação a objetos com uma terminologiachave. Onde quer que você olhe no mundo real, você vê objetos – pessoas,
animais, plantas, carros, aviões, edifícios, computares etc. Os seres humanos
pensam em termos de objetos. Telefones, casas, sinais de transito, fornos
microondas são apenas mais alguns objetos que vemos ao nosso redor todos os
dias. Os programas de computador, como os programas Java, também podem ser
vistos como objetos, compostos de uma grande quantidade de objetos de
softwares interativos.
Os objetos podem ser divididos e duas categorias: animados e
inanimados, objetos “vivos” – eles se movem e fazem coisas. Por outro lado, os
inanimados não se movem por conta própria. Objetos de ambos os tipos, porem,
tem algumas coisas em comum. Todos têm atributos (por exemplo, tamanho,
forma, cor e peso) e todos exibem comportamentos (por exemplo, uma bola rola,
rebate, infla, e murcha; o cachorro late, corre, pula e dorme; um carro acelera,
freia e desvia).
Projeto orientado a objetos (OOD – object-oriented design) – modela
softwares em termos semelhantes aqueles que as pessoas utilizam para
descrever objetos do mundo real. Ele tira proveito de relacionamentos de classe,
em que os objetos de certa classe, como uma classe de veículos, têm as mesmas
características, por exemplo: carros, caminhões, patins. O OOD (object-oriented
design) também tira proveito dos relacionamentos de herança, dos quais as
classes de objetos novos são derivadas absorvendo-se características de classes
existentes e adicionando-se características únicas dessas mesmas classes.
OOD encapsula (isto é, empacota) atributos e operações
(comportamentos) em objetos – os atributos e as operações de um objeto estão
intimamente ligados. Os objetos têm a propriedade de ocultar informações. Isso
significa que os objetos podem saber como se comunicar com os outros objetos
por meio de interfaces bem definidas, mas normalmente eles não tem permissão
para saber como os outros objetos foram implementados, os detalhes de
implementação são ocultados dentro dos próprios objetos. Na verdade podemos
dirigir um carro, por exemplo, sem conhecer os detalhes de como os motores,
transmissões, freios e sistemas de escapamento funcionam internamente,
contanto que saibamos utilizar o acelerador, o freio, e assim por diante. O
ocultamento de informações, como veremos, é crucial para a boa engenharia do
software.
O que é a UML?
A Unified Modeling Language é agora o esquema de representação
gráfica mais amplamente utilizada para modelar sistemas orientados a objetos. Ela
de fato unificou os vários esquemas de notações populares. Aqueles que projetam
sistemas utilizam a linguagem (na forma de diagramas) para modelar seus
sistemas.
Um recurso atraente da UML é sua flexibilidade. A UML é extensível
(isto é, capaz de ser aprimorada com novos recursos) e é independente de
qualquer processo OOAD particular. Os modeladores de UML são livres para
utilizar vários processos para modelar sistemas, e agora todos os
desenvolvedores podem expressar seus projetos com um conjunto padrão de
notações gráficas.
Veja alguns sites relacionados à UML na internet e Web.
- http://www.uml.org
- http://www.ibm.com/software/rational/uml
- http://pt.wikipedia.org/wiki/UML
Instalação do Java
Instalando o Java™ SE Development Kit 6 Update 2
Para iniciar a instalação execute o arquivo jdk-windows.exe.
A próxima janela a ser exibida é o contrato de licença, selecione
Accept.
Escolhendo o diretório de instalação para o JDK.
O diretório de instalação não necessita de ser alterado, para dar
continuidade selecione o botão Next.
Escolhendo o diretório de instalação para o JRE
Deixe também o diretório sem alteração e selecione o botão Next.
Progresso de instalação.
Para finalizar a instalação, selecione o botão Finish.
Configurando a Variável PATH
O ultimo passo antes de você poder utilizar o JDK é configurar a
variável de ambiente PATH para indicar onde s ferramentas do JDK são
instaladas.
Para iniciar a configuração, posicione o botão direito do mouse sobre o
ícone Meu Computador na área de trabalho e selecione Propriedades no menu.
Caixa de diálogo Propriedades do Sistema, iniciada.
Selecione a guia Avançado.
Ao selecionar a guia Avançado, selecione o botão
Ambiente.
Variáveis de
Caixa de diálogo Variáveis de Ambiente.
Editando a Variável PATH
Na caixa Variáveis de Sistema, selecione a variável PATH.
Ao selecionar a variável PATH, selecione o botão Editar.
Caixa de diálogo Editar variável de sistema.
Alterando o conteúdo da variável PATH
Posicione o cursor do mouse dentro do campo Valor da Variável.
Utilize a tecla de seta que aponta para esquerda e mova o cursor para o
começa da lista.
Agora que o cursor já se encontra no começo da lista, insira o nome do
diretório em que foi instalado o JDK.
Então adicione C:\Arquivos de programas\Java\ jdk1.6.0_02\bin; à
variável PATH.
Clique no botão <OK>, para completar a modificação variável PATH.
OBS: - Para que as configurações da variável PATH tenham efeito, é necessário
reiniciar seu computador.
Bibliotecas de classes do Java
Programas Java consistem em partes chamadas classes. As classes
incluem partes chamadas de métodos que realizam tarefas e retornam
informações ao concluir. Os programadores podem criar cada parte de que
precisam para formar os programas Java. Entretanto, a maioria dos
programadores Java tira proveito das ricas coleções de classes existentes nas
Bibliotecas de classe Java, que também são conhecidas como APIs do Java ou
Java APIs (application programming interfaces).
Uma classe de biblioteca Java serve a três propósitos dentro da
plataforma Java. Como outras bibliotecas padrão, elas disponibilizam ao
programador um conjunto de funções bem conhecidas que realizam tarefas
comuns, como a manutenção de listas de elementos ou manipulação de strings.
Em adição, a biblioteca contém uma interface para tarefas que dependem do
Hardware e do Sistema Operacional. Tarefas como o acesso à rede ou a arquivos
são altamente dependentes das capacidades nativas do ambiente. As bibliotecas
java.net e java.io implementam o código necessário internamente, e disponibilizam
uma interface padrão para que as aplicações Java possam executar essas
tarefas. Finalmente, se alguma plataforma não suportar alguma função que uma
aplicação Java necessita, as bibliotecas implementam esta funcionalidade usando
os recursos disponíveis, ou disponibilizando um meio consistente para que
aplicação verifique a presença de determinada funcionalidade.
Primeiro Programa Java – Imprimindo uma linha de texto
Um aplicativo Java é um programa de computador que é executado
quando você utiliza o comando Java para carregar a Java Virtual Machine (JVM).
Aplicativo simples para exibir uma linha de texto.
A linha 2
public class BemVindo
Se inicia com uma declaração de classe para a classe BemVindo.
Cada programa Java consiste em pelo menos uma declaração de classe que é
definida por você, o programador. Essas são conhecidas como classes definidas
pelo programador ou classes definidas pelo usuário. A palavra-chave class
introduz uma declaração de classe em Java e é imediatamente seguida pelo
nome da classe (BemVindo). As palavras-chave (ou palavras reservadas) são
reservadas para o uso pelo Java e sempre são escritas com todas as letras
maiúsculas.
Por convenção, todos os nomes de classes em Java iniciam com uma
letra maiúscula e apresentam a letra inicial de cada palavra que eles incluem em
maiúscula (por exemplo, SampleClassName). O nome de uma classe Java é um
identificador, uma série de caracteres que consiste em letras, dígitos, sublinhados
(_) e sinais de cifrão ($) que não iniciem com um dígito e não contenham espaços.
Alguns identificadores válidos são BemVindo, $valor, _valor, m_campo1
e botao5. O nome 5botao não é identificador válido porque inicia com um digito; e
o nome input field não é um identificador válido porque contém um espaço.
Normalmente, um identificador que não inicia com letra maiúscula não é nome de
classe Java. O Java faz distinção entre maiúsculas e minúsculas, isto é, letras
maiúsculas e letras minúsculas são diferentes, assim a1 e A1 são indicadores
diferentes (mas ambos válidos).
Dica:
- Por precaução, sempre inicie o identificador do nome de uma classe
com uma letra maiúscula e inicie cada palavra subseqüente no identificador com
uma letra maiúscula. Programadores Java sabem que esses identificadores
normalmente representam classes Java, portanto nomear suas classes dessa
maneira torna seus programadores mais legíveis.
Veja alguns erros comuns de programadores.
- O Java diferencia letras maiúsculas de minúsculas. A não utilização de
letras maiúsculas e minúsculas adequadas para um identificador normalmente
causa erro de compilação.
- É um erro de sintaxe se chaves não ocorrerem em pares
correspondentes.
A linha 4
// método principal inicia a execução do aplicativo Java
Sempre que encontrar duas barras (//) é onde foi inserido um
comentário sobre algum comando em especifico.
A linha 5
public static void main (String[ ] args)
É o ponto de partida de cada aplicativo Java. Os parênteses depois do
identificador main indicam que ele é um bloco de construção do programa
chamado método. Declarações de classe Java normalmente contêm um ou mais
métodos. Para um aplicativo Java, exatamente um dos métodos deve ser
chamado main e ser definido como mostrado na linha 5; caso contrario, a JVM não
executará o aplicativo. Os métodos são capazes de realizar tarefas e retornar
informações quando completam suas tarefas. A palavra-chave void indica que o
método realizará uma tarefa, mas não retornará nenhuma informação ao
completar sua tarefa.
A linha 7
System.out.println (“Bem Vindo a Programação em Java!”);
Instrui o computador a realizar uma ação, a saber, imprimir a string de
caracteres contida entre aspas duplas. Uma string ás vezes é chamada de string
de caracteres, uma mensagem ou uma string literal. Referimo-nos a caracteres
entre aspas duplas genericamente como strings.
System.out é conhecido como objeto de saída padrão. System.out
permite que aplicativos Java exibam conjuntos de caracteres na janela de
comando a partir da qual o aplicativo Java é executado. No Microsoft Window
95/98/ME, a janela de comando é o Promp do MS-DOS. No Microsoft Windows
NT/2000/XP, a janela de comando é o Promp de comando. No UNIX/Linux/Mac
OS X, a janela de comando é chamada de janela terminal ou shell. Muitos
programadores chamam a janela de comando simplesmente de linha de
comando.
O método System.out.println exibe (ou imprime) uma linha de texto na
janela de comando, A String entre parênteses na linha 7 é o argumento para o
método. O método System.out.println exibe (imprime) seu argumento na janela de
comando. Quando o System.out.println completa sua tarefa, ele posiciona o
cursor de saída (local em que o próximo caractere será exibido) no começo da
linha seguinte na janela de comando.
Alguns programadores acham difícil ler ou escrever um programa para
corresponder às chaves esquerda e direita ({ e }) que delimitam o corpo de uma
declaração de classe ou de uma declaração de método. Por esse motivo, os
programadores incluem um comentário de fim de linha depois de uma chave
direita de fechamento ( } ).
Por exemplo:
A linha 9
} // fim do método principal
Especifica a chave direita de fechamento ( } ) do metodo main.
A linha 11
} // fim da classe BemVindo
Compilando e executando seu primeiro aplicativo Java
Para compilar o programa, abra uma janela de comando (Promp de
Comando) e vá para o diretório onde o programa está armazenado. A maioria dos
sistemas operacionais utiliza o comando cd para mudar de diretório. Por
exemplo:
cd c:\projetos\java
muda para o diretório java no Windows.
Após indicar o arquivo, vamos compilar nosso programa, digitando.
javac BemVindo.java
Se programa não contiver nenhum arquivo erro de sintaxe, o comando
anterior cria um novo arquivo chamado BemVindo.class (conhecido como arquivo
de classe para BemVindo) que contém os bytecodes Java que representam
nosso aplicativo. Quando utilizarmos o comando java para executarmos o
aplicativo, esses bytecodes serão executados pela JVM.
Veja algumas dicas de prevenção de erros.
- O compilador Java gera mensagens de erro de sintaxe quando a
sintaxe de um programa está incorreta. Cada mensagem de erro contém o nome
do arquivo e o número da linha em que o erro ocorreu.
- A mensagem de erro do compilador “Public class NomeDaClasse must
be defined in a file called NomeDaClasse.java” indica que o nome do arquivo não
corresponde exatamente ao nome da classe public no arquivo ou que o nome da
classe foi digitado incorretamente ao compilar a classe.
Para compilar o programa, no Promp de comando, insira a linha de
comando.
Java BemVindo
Este comando carrega a JVM, que carrega o arquivo “.class” para a
classe BemVindo. Observe que a extensão de nome de arquivo “.class” é omitida
do comando precedente; caso contrário a JVM não executará o programa. A JVM
chamará o método main, em seguida, a instrução da linha 7 do main exibe
“BemVindo a Programação em Java!”.
- Ao tentar executar um programa Java, se receber uma mensagem
como “Exception in thread ‘main’ java.langNoClassDefFoundError: BemVindo”,
sua variável de ambiente CLASSPATH não foi configurada adequadamente.
Modificando nosso primeiro programa Java
Exibindo uma única linha de texto com múltiplas instruções
Bem Vindo à programação em Java! pode ser exibido de várias
maneiras. Daqui para frente, destacaremos os novos recursos e os recursoschave em cada listagem de código.
Imprimindo uma linha de texto com múltiplas instruções
// Imprimindo uma linha de texto com múltiplas instruções.
É um comentário de fim de linha declarando o propósito desse
programa. A linha 4 inicia a declaração da sua classe BemVindo1.
As linhas 9-10 do método main:
System.out.print(“Bem Vindo a “)
System.out.println(“Programação em Java!”);
Exibem uma linha de texto na janela de comando. A primeira instrução
utiliza o método print de System.out para exibir uma string. Diferentemente de
println, depois de exibir seu argumento, print não posiciona o cursor de saída no
começo da próxima linha na janela de comando, o próximo caractere que o
programa exibe aparecerá logo depois do ultimo caractere que print exibe.
Portanto, a linha 10 posiciona o primeiro caractere no seu argumento (a letra “P”)
imediatamente depois do ultimo caractere que a linha 9 exibe ( o caractere de
espaço em branco antes da aspa dupla de fechamento da string ). Cada instrução
print ou println retoma a exibição dos caracteres a partir de onde a ultima instrução
print ou println parou de exibir os caracteres.
Exibindo múltiplas linhas de texto com uma única instrução
// Imprimindo múltiplas linhas de texto com uma única instrução.
É um comentário que declara o propósito desse programa. A linha 4
inicia a declaração da classe BemVindo2.
A linha 9
System.out.print (“Bem Vindo a\nProgramacao\nem Java!”)
Exibe três linhas separadas de texto na janela de comando.
Normalmente, os caracteres em uma string são exibidos exatamente como
aparecem entre aspas duplas. Observe, porém que os dois caracteres \ e n
(repetidos duas vezes na instrução) não aparecem na tela. A barra invertida ( \ )
é chamada de caractere de escape. Isso índica aos métodos print e println de
System.out que um “caractere especial” deve ser impresso. Quando aparece uma
barra invertida em uma strings de caracteres, o Java combina o próximo
caractere com as barras invertidas para formar uma seqüência de escape. A
seqüência de escape \n representa o caractere de nova linha. Quando um
caractere de nova linha aparece em uma string sendo enviada para a saída com
System.out, o caractere de nova linha faz com que o cursor de saída na tela se
mova para o começo da próxima linha na janela de comando.
Algumas seqüências de escape comuns.
\n – Nova linha. Posiciona o cursor de tela no inicio da próxima linha.
\t – Tabulação horizontal. Move o cursor de tela para a próxima linha de
tabulação.
\r – Retorno de carro. Posiciona o cursor da tela no inicio da linha atual,
não avança para a próxima linha. Qualquer saída de caracteres depois do retorno
de carro sobrescreve a saída de caracteres anteriormente gerados na linha atual.
\\ - Barras invertidas. Utilizadas para imprimir um caractere de barra
invertida.
\” – Aspas duplas. Utilizadas para imprimir um caractere de aspas
duplas. Por exemplo, System.out.println (
);
Exibe “Java”.
Aplicativos Java – Adicionando inteiros
Um aplicativo que lê (ou insere) dois inteiros (números integrais, como 22, 7, 0 e 1.024) digitados por um usuário no teclado, calcula a soma dos valores
e exibe o resultado. Esse programa deve manter um registro de números
fornecidos pelo usuário para o calculo mais tarde no programa. Os programas
lembram dos números e de outros dados na memória do computador e acessam
esses dados por meio de elementos de programa chamados variáveis.
A linha 2
Declara o nome do arquivo e o propósito do programa.
A linha 3
import java.util.Scanner; // programa utiliza a classe Scanner
É uma declaração import que ajuda o computador a localizar uma
classe utilizada nesse programa. Um dos pontos fortes do Java é o seu rico
conjunto de classes predefinidas que os programadores podem reutilizar em vez
de “reinvenatr a roda”. Essas classes são agrupadas em pacotes, chamados de
coleções de classes. Coletivamente, pacotes do Java são chamados de
biblioteca de classes Java ou Java Application Programming Interface ( API
do Java ). Os programadores utilizam declarações import para identificar as
classes predefinidas utilizadas em um programa Java.
A linha 5
public class Adicao
Começa a declaração da classe Adicao. O nome de arquivo para essa
classe public deve ser Adicao.java.
A linha 11
Scanner input = new Scanner(System.in);
É uma instrução de declaração de variável (ou declaração) que
especifica o nome e o tipo de uma variável (input) que é utilizado nesse programa.
Uma variável é uma posição na memória do computador onde um valor pode ser
armazenado para a utilização posterior em um programa. Todas as variáveis
devem ser declaradas com um nome e um tipo antes de poderem ser utilizadas.
O nome de uma variável permite que o programa acesse o valor da variável na
memória. O nome de uma variável pode ser qualquer identificador válido. O tipo
de uma variável especifica o tipo de informações armazenadas nessa posição na
memória. Como ocorrem com outras instruções, as instruções de declaração
terminam com um ponto-e-vírgula ( ; ).
A declaração na linha 11 especifica que a variável nomeada input seja
do tipo Scanner. Um Scanner permite a um programa ler os dados (por exemplo,
números) para a utilização em um programa. Os dados podem ser provenientes
de varias origens, como de um arquivo no disco ou digitados pelo usuário.
O sinal de (=) na linha 11 indica que a variável Scanner input deve ser
iniciada (isto é, preparada para utilização no programa) na sua declaração com o
resultado da expressão new Scanner(System.in) à direita do sinal de igual. Essa
expressão cria um objeto Scanner que lê o tipo de dados digitados pelo usuário.
Lembre-se de que o objeto de saída padrão, System.in, permite que aplicativos
Java leiam as informações digitadas pelo usuário. Portanto, a linha 11 cria um
Scanner que permite ao aplicativo ler as informações digitadas pelo usuário.
As instruções de declaração de variável nas linhas 13-15
int numero1; // primeiro número a somar
int numero2; // segundo número a somar
int soma; // soma de numero1 e numero2
Declaram que as variáveis numero1, numero2 e soma são dados do tipo
int, essas variáveis conterão valores inteiros (números integrais como 7, -11, 0 e
31.914). Essas variáveis ainda não são iniciadas. O intervalo de valores para o int
é -2.147.483.648 a +2.147.483.647. Os números reais são números que contém
pontos de fração decimal, como 3.4, 0.0 e -11.19. Variáveis do tipo char
representam caracteres individuais, como uma letra maiúscula (por exemplo, A),
um dígito (por exemplo, 7), um caractere especial (por exemplo, * ou %) ou uma
seqüência de escape (por exemplo, o caractere de nova linha, \n). Tipos como int,
float, double e char são freqüentemente chamados de tipos primitivos ou tipos
predefinidos. Os nomes dos tipos primitivos são palavras-chave e, portanto,
devem aparecer em letras minúsculas. O Apêndice D resume as caracteriscas dos
oito tipos primitivos (boolean, byte, char, short, int, long, float e double).
As instruções de declaração de variável podem ser divididas em várias
linhas, com os nomes de variáveis separados por vírgulas (isto é, uma lista
separada por vírgulas de nomes de variáveis). Diversas variáveis do mesmo tipo
podem ser declaradas em uma declaração ou em múltiplas declarações. Por
exemplo, as linhas 13-15 também podem ser escritas desta maneira.
int numero1; // primeiro número a somar
numero2; // segundo número a somar
soma; // soma de numero1 e numero2
A linha 17
System.out.print(“Digite o primeiro número: “); // prompt
Utiliza System.out.print para exibir a mensagem “Digite o primeiro
número:”. Essa mensagem é chamada de prompt porque direciona o usuário para
uma ação específica. Como vimos nas páginas anteriores os identificadores que
se iniciam com letras maiúsculas representam nome de classe. Portanto, System
é uma classe. A classe System faz parte do pacote java.lang. Observe que a
classe System não é importada com uma declaração import no começo do
programa.
A linha 18
Numero1 = input.nextInt( ); // lê o primeiro número fornecido pelo
usuário
Utiliza o método nextInt do valor de input do objeto Scanner para obter
um inteiro digitado pelo usuário. Nesse momento o programa espera que o usuário
digite o número e pressione a tecla <Enter> para submeter o número para o
programa.
Ainda na linha 18, o resultado da chamada ao método nextInt (um valor
int) é colocado na variável numero1 utilizando o operador de distribuição, =. A
instrução é lida como “numero1 obtém o valor de input.nextInt( )”. O operador = é
chamado de operador binário porque tem dois operandos, numero1 e o resultado
da chamada do método input.nextInt( ). Essa instrução é chamada de instrução
de atribuição porque é uma instrução que atribui um valor a uma variável. Tudo
que aparece a direita do operador de atribuição, =, sempre é avaliado antes de a
atribuição ser realizada.
A linha 20
System.out.print( “Digite o segundo número: “); //prompt
Pede para o usuário inserir o segundo inteiro.
A linha 21
numero2 = input.nextInt( ); // lê o segundo número fornecido pelo
usuário
Lê o segundo inteiro e o atribui à variável numero2
A linha 23
soma = numero1 + numero2; // soma os números
É uma instrução de atribuição que calcula a soma das variáveis
numero1 e numero2 e atribui o resultado a variável soma utilizando o operador de
atribuição, =. A instrução é lida como “= obtém o valor de numero1 + numero2”. A
maioria dos cálculos é realizada em instruções de atribuição. Quando o programa
encontra a operação de adição, ele utiliza os valores armazenados nas variáveis
numero1 e numero2 para realizar o cálculo. Na instrução anterior, o operador de
adição é um operador binário, seus dois operandos são numero1 e numero2. As
partes das instruções que contêm os cálculos são chamadas de expressões. De
fato, uma expressão é qualquer parte de uma instrução que tem um valor
associado a ela. Por exemplo, o valor da expressão numero1 + numero2 é soma
dos números. De maneira semelhante, o valor da expressão input.nextInt( ) é um
valor inteiro digitado pelo usuário.
Depois que o cálculo foi realizado, a linha 25.
System.out.println(“A soma e: “+Integer.toString(soma)); // exibe a soma
Utiliza o método System.out.println para exibir a variável soma. O
especificador +Integer.toString, acrescenta uma nova string, para realizar a soma.
Classes, Objetos, Métodos e Variáveis de Instância
Para realizar uma tarefa em um programa é necessário um método. O
método descreve os mecanismos que realmente realizam suas tarefas. O método
oculta de seu usuário as tarefas complexas que ele realiza. Em Java, primeiro
criamos uma unidade chamada classe para abrigar um método. Em uma classe,
você fornece um ou mais métodos que são projetados para realizar as tarefas da
classe. Por exemplo, uma classe que representa uma conta bancária poderia
conter um método para fazer depósitos de dinheiro em uma conta, outro para
fazer saques e um terceiro para perguntar qual é o saldo atual.
Assim como você não pode dirigir um desenho de engenharia de um
carro, você não pode “dirigir” uma classe. Assim como alguém tem que construir
um carro a partir de seus desenhos de engenharia antes de você realmente guiar
o carro, você deve construir um objeto de uma classe antes de fazer um programa
realizar as tarefas que a classe descreve como fazer. Essa é uma razão de o Java
ser conhecido como uma linguagem de programação orientada a objetos.
Ao dirigir um carro, o ato de pressionar o acelerador envia uma
mensagem para o carro realizar uma tarefa, isto é, fazer o carro andar mais
rápido. De maneira semelhante, você envia mensagens para um objeto, cada
mensagem é reconhecida como uma chamada de método e instrui um método do
objeto a realizar sua tarefa.
Como as capacidades de um carro, esses atributos estão sempre
associados com o carro. Cada carro mantém seus próprios atributos. Por exemplo,
cada carro sabe a quantidade de gasolina que há em seu tanque, mas não sabe
quanto há no tanque de outros carros. De maneira semelhante, um objeto tem
atributos que são portados com o objeto quando ele é utilizado em um programa.
Esses atributos são especificados com a parte da classe do objeto. Por exemplo,
um objeto conta bancária tem um atributo saldo que representa a quantidade de
dinheiro na conta. Cada objeto conta bancária sabe o saldo da conta que ele
representa, mas não sabe os saldos de outras contas no banco. Os atributos são
especificados pelas variáveis de instância da classe.
Declarando uma classe com um método e instanciando um objeto de
uma classe
Classe LivroGrau
A declaração da classe LivroGrau (imagem acima) contém um método
displayMessage, que exibe uma mensagem na tela. A linha 9 da classe realiza o
trabalho de exibir a mensagem. Lembre-se de que uma classe é como uma planta
arquitetônica precisará fazer um objeto dessa classe e chamar seu método para
que a linha 9 execute e exiba sua mensagem.
A declaração da classe se inicia na linha 4. A palavra-chave public é um
modificador de acesso. Por enquanto, simplesmente declaramos toda a classe
public. Cada declaração de classe contém uma palavra-chave class seguida
imediatamente do nome da classe. O corpo de cada classe está emtre as chaves
esquerda e direita ({ e }), como nas linhas 5 e 12 da classe LivroGrau.
A declaração de método começa com a palavra-chave public para
indicar que o método está “disponível para o público”, isto é, pode ser chamado de
fora do corpo da declaração de classe por métodos de outras classes. A palavrachave void indica que esse método realizará uma tarefa, mas não retornará (isto é,
não devolverá) nenhuma informação para seu método de chamada ao completar
sua tarefa. Já utilizamos métodos que retornam informações em lições anteriores,
como por exemplo, você utilizou o método Scanner nextInt para inserir um inteiro
digitado pelo usuário no teclado. Quando nextInt insere um valor, ele retorna esse
valor para a utilização no programa.
O nome do método, displayMessage, segue o tipo de retorno. Por
convenção, os nomes de método iniciam com a primeira letra minúscula e todas
as palavras subseqüentes no nome iniciam com letra maiúscula. Os parênteses (
), depois do nome do método indicam que isso é um método. Um conjunto vazio
de parênteses, como mostrado na linha 7, indica que esse método não requer
informações adicionais para realizar sua tarefa. A linha 7 é comumente referida
como cabeçalho de método. O corpo de cada método é delimitado pelas chaves
esquerda e direita ({ e }), como nas linhas 8 e 10.
Uma classe que contém o método main é um aplicativo Java. Essa
classe é especial porque a JVM pode utilizar main para iniciar a execução. A
classe LivroGrau não é um aplicativo porque não contém o método main.
Compilando o aplicativo que não contém o método main.
Classe contendo o método main.
Classe LivroGrauTeste
A declaração de classe LivroGrauTeste, contém o método main que
controlará a execução do nosso aplicativo. Qualquer classe que contém main
declarado, como mostrado na linha 7, pode ser utilizada para executar um
aplicativo. Essa declaração de classe contém somente um método main, que é
típico de muitas classes que iniciam a execução de um aplicativo.
As linhas 7 e 14 declaram o método main. Lembre-se que o cabeçalho
main deve aparecer como mostrado na linha 7, caso contrário, o aplicativo não
executará. Uma parte-chave para permitir à JVM localizar e chamar o método
main para iniciar a execução do aplicativo é a palavra-chave static (linha 7), que
indica que main é um método static. Um método static é especial porque pode ser
chamado sem primeiro criar um objeto da classe em que o método é declarado.
Neste aplicativo gostaríamos de chamar o método displayMessage da classe
LivroGrau para exibir a mensagem de boas-vindas na janela de comando. Em
geral, você não pode chamar um método que pertence a outra classe até criar um
objeto dessa classe, como mostrado na linha 10.
Assim como podemos utilizar o objeto System.out para chamar métodos
print, printf e println, agora pode utilizar meuLivroGrau para chamar o método
displayMessage. A linha 13 chama o método displayMessage que utiliza a variável
meuLivroGrau seguida por um separador ponto (.), o nome do método
displayMessage e um conjunto vazio de parênteses. No começo da linha 13,
“meuLivroGrau.” indica que main deve utilizar o objeto LivroGrau que foi criado na
linha 10. A linha 7 do primeiro programa que criamos somente a classe (aplicativo
anterior), indica que o método displayMessage tem uma lista vazia de parâmetros,
isto é, displayMessage não requer informações adicionais para realizar sua tarefa.
Por essa razão, a chamada de método especifica um conjunto vazio de
parênteses depois do nome do método displayMessage. Quando o método
displayMessage completa sua tarefa, o método main continua a executar na linha
14. Esse é o fim do método main, portanto o programa termina.
Compilando um aplicativo com múltiplas classes
Para compilar ambas as classes de uma só vez utilize o comando
abaixo.
javac LivroGrau.java LivroGrauTeste.java
Variáveis de instância, métodos set e get
Uma classe normalmente consiste em um ou métodos que manipulam
os atributos que pertencem a um objeto particular da classe. Os atributos são
representados como variáveis em uma declaração de classe. Essas variáveis são
chamadas de campos e são declaradas dentro de uma declaração de classe, mas
fora dos corpos das declarações de método da classe. Quando cada objeto de
uma classe mantém sua própria cópia de um atributo, o campo que representa o
atributo também é conhecido como uma variável de instância, cada objeto
(instância) da classe tem uma instância separada da variável na memória.
Classe LivroGrau3 com um variável de instância, um método set e um
método get
A linha 7 declara que nomeCurso é uma variável de tipo String. Como a
variável é declarada no corpo da classe (linha 6-30), mas fora dos corpos dos
métodos da classe (linhas 10-13, 16-19 e 22-28), a linha 7 é uma declaração para
variável de instância. Toda instância (isto é, objeto) de classe LivroGrau2 contém
uma cópia de cada variável de instância.
Modificadores de acesso public e private
A maioria das declarações de variável de instância é procedida pela
palavra-chave private (como na linha 7). Como public, a palavra-chave private é
um modificador de acesso. As variáveis ou métodos declarados com o modificador
de acesso private só são acessíveis a métodos da classe em que são declarados.
Portanto, a variável nomeCurso só pode ser utilizada nos métodos setNomeCurso
getNomeCurso e displayMessage (de cada objeto) da classe LivroGrau2.
O método setNomeCurso (linhas 10-13) não retorna quaisquer dados
quando ele completa sua tarefa, portanto seu tipo de retorno é void. O método
recebe um parâmetro, nome, que representa o nome do curso que será passado
para o método como um argumento. A linha 12 atribui nome à variável de
instância nomeCurso.
O método getNomCurso (linhas 16-19) retorna um nomeCurso do objeto
LivroGrau2 particular. O método tem uma lista vazia de parâmetros, então não
exige informações adicionais para realizar sua tarefa. O método especifica que ele
retorna uma String, isso é conhecido como tipo de retorno do método. Quando um
método retornará um resultado para seu método chamador.
O método displayMessage (linhas 22-28) não retorna quaisquer dados
quando ele completa sua tarefa, portanto seu tipo de retorno é void. O método não
recebe parâmetros, então a lista de parâmetros está vazia. As linhas 26-27 geram
saída de uma mensagem de boas-vindas que inclui o valor de variável de
instância nomeCurso. Mais uma vez, precisamos criar um objeto de classe
LivroGrau2 e chamar seus métodos antes que a mensagem de boas-vindas possa
ser exibida.
Criando e manipulando um objeto LIvroGrau2
Aplicativo sendo executado.
Métodos set e get
Os campos private de uma classe só podem ser manipulados por
métodos dessa classe. Então um cliente de um objeto, isto é, qualquer classe
que chama os métodos do objeto, chama os métodos public da classe para
manipular os campos private de um objeto da classe. Essa é a razão por que as
instruções no método main chamam os métodos setNomeCurso, getNomeCurso e
displayMessage em um objeto LivroGrau2. As classes costumam fornecer
métodos public para permitir a clientes da classe configurar (set, isto é, atribuir
valores a ) ou obter (get, isto é, obter valores de ) variáveis de instância private.
Os nomes desses métodos não precisam começar com set ou get, mas essa
convenção de atribuição de altamente recomendada em Java e é requerida para
componentes de software Java especiais denominados JavaBeans, que podem
simplificar a programação em muitos ambientes de desenvolvimento integrado
Java (integrade development environments – IDEs). O método que configura (set)
a variável de instância nomeCurso nesse exemplo chama-se setNomeCurso, o
método que obtém (get) o valor da variável de instância nomeCurso chama-se
getNomeCurso.
Inicializando objetos com construtores
Cada classe que se declara pode fornecer um construtor que pode ser
utilizado para iniciar um objeto de uma classe quando o objeto for criado. De fato,
o Java requer uma chamada de construtor para todo objeto que é criado. A
palavra-chave new chama o construtor da classe para realizar inicialização. A
chamada do construtor é indicada pelo nome da classe seguido por parênteses.
Por exemplo, a linha 14 utiliza o primeiro new para criar um objeto LivroGrau2. Os
parênteses vazios depois de “newLivroGrau” indicam uma chamada ao construtor
da classe sem argumentos. Por padrão, o compilador fornece um construtorpadrão sem parâmetros em qualquer classe que não inclua explicitamente um
construtor.
Ao declarar uma classe, você pode fornecer seu próprio consrtutor a fim
de especificar a inicialização personalizada para objetos de sua classe. Por
exemplo, um programador poderia querer especificar o nome de um curso para o
objeto LIvroGrau2 quando o objeto fosse criado, como em:
LivroGrau2 meuLivroGrau = new LivroGrau2 ( “01 Introdução de
Programação em Java” );
Nesse caso, o argumento “01 Introdução de Programação em Java” é
passado para o construtor do objeto LivroGrau2 e utilizado para iniciar
nomeCurso. A instrução anterior exige que a classe forneça um construtor com
parâmetro String.
A classe LivroGrau3 modificada por um construtor.
As linhas 9-12 declaram o construtor para a classe LivroGrau3. Um
construtor deve ter o mesmo nome de sua classe. Como um método, um
construtor especifica em sua lista de parâmetros os dados que ele requer para
realizar sua tarefa. Quando você criar um novo objeto, esses dados são colocados
nos parênteses que seguem ao nome da classe. A linha 9 indica que o construtor
da classe LivroGrau3 tem um parâmetro chamado nome de tipo String. Na linha
11 do corpo do construtor, o nome passado para o construtor é atribuído à variável
de instancia nomeCurso.
Construtores criados para inicializar os objetos LivroGrau3.
Aplicativo sendo executado.
Números de ponto flutuante e tipo double
Precisão de número de ponto flutuante e requisitos de memória
As varáveis de tipo float representam números de pontos flutuantes
de precisão simples e têm sete dígitos significativos. As variáveis de tipo double
representam números de ponto flutuante de dupla precisão. Essas requerem
duas vezes a quantidade de memória das variáveis float e fornecem 15 dígitos
significativos, aproximadamente o dobro da precisão de variáveis float. Para o
intervalo de valores requerido pela maioria dos programas, as variáveis do tipo
float devem bastar, mas você pode utilizar double para “trabalhar com segurança”.
Em alguns aplicativos, até mesmo as variáveis do tipo double serão inadequadas.
A maioria dos programadores representa números de ponto flutuante com o tipo
double. De fato, o Java trata todos os números de ponto flutuante que você digita
no código-fonte de um programa (como 7,33 e 0,0975) como valores double e por
padrão. Esses valores no código-fonte são conhecidos como literais de ponto
flutuante.
Classe Conta com uma variável de instancia do tipo double.
A classe Conta contém um construtor e dois métodos. Uma vez que é
comum alguém abrir ma conta pra colocar dinheiro imediatamente, o construtor
(10-16) recebe um parâmetro inicialBalanco do tipo double que representa o sald
inicial da conta. As linhas 14-15 asseguram que inicialBalanco seja maior que 0.0.
Se for, o valor de inicialBalanco é atribuído a variável de instância balanço. Caso
contrário, balanco permanece em 0.0, seu valor inicial padrão.
O método credito (linhas 19-22) não retorna quaisquer dados quando
ele completa sua tarefa, portanto seu tipo de retorno é void. O método recebe um
parâmetro chamado quantia, um valor double que será adicionado ao saldo. A
linha 21 adiciona quantia ao valor atual de balanço, então atribui o resultado ao
balanço (substituindo assim a quantia do saldo anterior).
O metodo getBalanco (linhas 25-28) permite aos clientes da classe (isto
é, outras classes que utilizam essa classe) obter o valor do balanco de um objeto
Conta particular. O método especifica o tipo de retorno double e uma lista vazia de
parâmetros.
Mais uma vez, observe que as instruções nas linhas 15, 21 e 27 utilizam
a variável de instância balanço mesmo se ela não tiver sido declarada em nenhum
dos métodos. Podemos utilizar balanco nesses métodos porque ele é uma variável
de instância da classe.
Classe Conta Teste para utilizar a classe Conta_
Entre com as quantias desejadas e observe os valores inseridos.
GUIs e imagens gráficas – Utilizando caixas de diálogo
Muitos aplicativos Java utilizam janelas ou caixas de diálogo
(também chamadas de diálogos) para exibir a saída. Por exemplo,
navegadores da World Wide Web como Mozilla Firefox ou Microsoft
Internet Explorer exibem paginas da Web em suas próprias janelas. Os
programas de correio eletrônico permitem digitar e ler mensagens em uma
janela. Em geral, as caixas de diálogo são janelas nas quais os programas
exibem mensagens importantes para o usuário do programa. A classe
JOptionPane fornece caixas de diálogo pré-empacotadas que permitem
aos programas exibir janelas que contém mensagens para o usuário, essas
janelas são chamadas de diálogos de mensagem.
Aplicativo, classe Dialogo.
Aplicativo executado, caixa de diálogo ativa.
A linha 3 indica que nosso programa utiliza a classe JOptionPane do
pacote javax.swing. Esse pacote contém muitas classes que ajudam os
programadores em Java a criar interfaces gráficas com usuário (garphical user
interfaces – GUIs) para aplicativos. Os componentes GUI facilitam a entrada de
dados do usuário de um programa e a formação ou apresentação de saídas de
dados para o usuário. No método main, a linha 10 chama o método
showMessageDialog da classe JOptionPane para exibir uma caixa de diálogo
que contém uma mensagem. O método requer dois argumentos. O primeiro
argumento ajuda o aplicativo Java a determinar onde posicionar a caixa de
diálogo. Quando o primeiro argumento for null, a caixa de diálogo aparece no
centro da tela do computador. O segundo argumento é a String a ser exibida a
caixa de diálogo.
ShowMessageDialog é um método especial da classe JOptionPane
chamado de método static. Esses métodos costumam definir tarefas
frequentemente utilizadas que não exigem explicitamente a criação de um objeto.
Por exemplo, muitos programas exibem mensagens para usuários em caixas de
diálogo. Em vez de exigir que os programadores criem o código que realiza essa
tarefa, os projetores da classe JOptionPane do Java declaram um método static
para esse propósito. Agora, com uma chamada de método simples, todos os
programadores podem fazer um programa exibir uma caixa de diálogo que
contenha uma mensagem. Em geral, um método static é chamado utilizando seu
nome de classe seguido por um ponto (.) e o nome de método, como em:
NomeDaClasse.nomeDoMetodo(argumentos)
Inserindo texto em uma caixa de diálogo
O próximo aplicativo vai demonstrar a entrada utilizando diálogos. Este
programa utiliza outra caixa de diálogo predefinida JOptionPane chamada de
diálogo de entrada que permite ao usuário inserir dados para utilização no
programa. O programa pede o nome de usuário e responde com um cumprimento
contendo o nome inserido pelo usuário.
Programa executado.
As linhas 10-11 utilizam o método showInputDialog da classe
JOptionPane para exibir um diálogo de entrada simples que contém um prompt e
um campo para o usuário inserir texto, campo esse conhecido como campo de
texto. O argumento para showInputDialog é o prompt que indica o nome que o
usuário deve inserir. O usuário digita caracteres no campo de texto, depois clica
no botão OK ou pressiona a tecla ENTER para retornar a String para o programa.
O método showInputDialog retorna uma String que contém o caractere digitado
pelo usuário, que armazenamos na variável nome.
As linhas 14-15 utilizam o método static String format para retornar uma
String que contém uma saudação com o nome inserido pelo usuário. O método
format é semelhante ao método System.out.printf, exceto pelo fato de que format
retorna uma String formatada em vez de exibi-la em uma janela de comando. A
linha 18 exibe a saudação em um diálogo de mensagem.
Entrada/Saída baseada em GUI simples com JOptionPane
A classe JOtionPane do Java (pacote javax.swing) fornece caixas de
diálogo pré-empacotadas tanto para entrada quanto para saída. Esses diálogos
são exibidos invocando métodos JOptionPane static.
Aplicativo utilizando dois diálogos de entrada para obter inteiros do
usuário e um diálogo de mensagem para exibir a subtração dos inteiros que o
usuário insere.
Aplicativo compilado e executado.
Constantes de diálogo de mensagem JOptionPane
As constantes que representam os tipos de diálogo de mensagem são
mostradas na imagem abaixo. Todos os tipos de mensagem, exceto
PLAIN_MESSAGE, exibem um ícone à esquerda da mensagem. Esses ícones
fornecem uma indicação visual da importância da mensagem para o usuário.
Instruções de controle
Instruções de seleção em Java
O Java contém três tipos de instruções de seleção. A instrução if realiza
(seleciona) uma ação se uma condição for verdadeira ou pula a ação se a
condição for falsa. A instrução if...else realiza uma ação se uma condição for
verdadeira e realiza uma ação se a condição for falsa. A instrução de seleção
switch realiza uma de muitas ações diferentes, dependendo do valor de uma
expressão.
A instrução if é uma instrução de uma única seleção porque seleciona
ou ignora uma única ação ou um grupo de ações. A instrução if...else é chamada
instrução de seleção dupla porque seleciona entre duas ações diferentes ou
grupos de ações. A instrução switch é chamada de instrução de seleção
múltipla uma vez que seleciona entre muitas ações diferentes, grupos de ações.
Instruções de repetição em Java
O Java fornece três tipos de instruções de repetições (também
chamadas de instruções de loop) que permitem aos programas executar
instruções repetidamente, contanto que uma condição (chamada condição de
continuação de loop) permaneça verdadeira. As instruções de repetição são as
instruções while, do...while e for. As instruções while e for realizam a ação (ou
grupo de ações) no seu corpo zero ou mais vezes, se a condição de continuação
de loop for inicialmente falsa, a ação (ou grupo de ações) não será executada. A
instrução do...while realiza a ação (ou grupo de ações) no seu corpo uma ou mais
vezes.
A instrução de uma única seleção if
Os programas utilizam instruções de seleção para escolher entre os
cursos alternativos de ações. Por exemplo, suponha que a nota de aprovação de
um exame seja 10.
If (SE) a nota do aluno é maior que ou igual a 10
Imprima ‘Aprovado’
A instrução em pseudocódigo: determina se a condição “nota do aluno é
maior que ou igual a 10” é verdadeira ou falsa. Se a condição for verdadeira,
“Aprovado” é impresso e a próxima instrução em pseudocódigo na ordem é
“realizada”. (Lembre-se de que o pseudocódigo não é uma linguagem de
programação real.) Se a condição for falsa, a instrução Imprima é ignorada e a
próxima instrução de pseudocódigo na seqüência é realizada. O recuo da segunda
linha dessa instrução de seleção é opcional, mas recomendável, porque enfatiza a
estrutura inerente dos programas estruturados.
A instrução de pseudocódigo If precedente pode ser escrita em Java
como:
if ( notadoEstudante > = 10 )
System.out.println ( “Aprovado” );
A instrução de seleção dupla if...else
A instrução if de uma única seleção realiza uma ação indicada somente
quando a condição é true; caso contrário, a ação é pulada. A instrução if...else
permite que o programador especifique uma ação a realizar a condição verdadeira
e uma ação diferente quando a condição é falsa.
If (Se) a nota do aluno é maior que ou igual a 10
Imprime ‘Aprovado’
Else (caso contrário)
Imprime ‘Reprovado’
Por exemplo, a instrução acima em pseudocódigo, imprime “Aprovado”
se a nota do aluno for maior que ou igual a 10, mas imprime “Reprovado” se for
menor que 10. Em qualquer um dos casos, depois que a impressão ocorre, a
próxima instrução do pseudocódigo na seqüência é “realizada”
A instrução If...Else no pseudocódigo anterior pode ser escrita em Java
assim:
if (nota > = 10)
System.out.println ( “Aprovado” );
else
System.out.println ( “Reprovado” );
Operador condicional (?:)
O Java fornece o operador condicional (?:) que pode ser utilizado no
lugar de uma instrução if...else. Esse é o único operador ternário do Java,
significa que ele recebe três operandos. Juntos, os operandos e o símbolo ?:
formam uma expressão condicional. O primeiro operando (à esquerda do ?) é
uma expressão booleana (isto é, uma condição que é avaliada como um valor
boolean, true ou false), o segundo operando (entre o ? e :) é o valor da expressão
condicional se a expressão boolean for true, e o terceiro operando (á direita do :) é
o valor da expressão condicional se a expressão boolean for avaliada como false.
System.out.println( notadoEstudante >= 10? “Aprovado” : “Reprovado” );
A instrução acima, imprime o valor do argumento da expressão
condicional de println. A expressão condicional nessa instrução é avaliada para
string ”Aprovado” se a expressão boolean notadoEstudante>=10 for verdadeira e
é avaliada para string “Reprovado” se a expressão booleana for falsa. Portanto,
essa instrução com o operador condicional realiza essencialmente a mesma
função da instrução if...else mostrada anteriormente. A precedência do operador
condicional é baixa, então a expressão condicional inteira normalmente é colocada
entre parênteses.
Instruções if...else aninhadas
Um programa pode testar múltiplos casos colocando instruções if...else
dentro de outras instruções if...else para criar instruções if...else aninhadas. O
exemplo pseudocódigo que veremos a seguir representa uma if...else aninhada
que imprime A para notas de exame maiores ou iguais a 90, B para notas no
intervalo de 80 a 89, C para notas no intervalo 70 a 79, D para notas no intervalo
60 a 69 e F para todas as outras notas.
If (Se) a nota do aluno é maior que ou igual 90
Imprima ‘A’
else (caso contrário)
If (Se) a nota do aluno é maior que ou igual 80
Imprima ‘B’
else (caso contrário)
If (Se) a nota do aluno é maior que ou igual 70
Imprima ‘C’
else (caso contrário)
If (Se) a nota do aluno é maior que ou igual 60
Imprima ‘D’
else (caso contrário)
Imprima ‘F’
Esse pseudocódigo pose ser escrito em Java como:
if (notaEstudante >= 90)
System.out.println( “A” );
else
if (notaEstudante >= 80)
System.out.println( “B” );
else
if (notaEstudante >= 70)
System.out.println( “C” );
else
if (notaEstudante >= 60)
System.out.println( “D” );
else
System.out.println( “F” );
Se notaEstudante for maior ou igual a 90, as primeiras quatro condições
serão verdadeiras, mas somente a instrução na parte if da primeira instrução
if...else será executada. Depois que essa instrução é executada, a parte else
“mais externa” da instrução if...else é pulada. A maioria dos programadores Java
prefere escrever a instrução if...else anterior desta maneira.
if (notaEstudante >= 90 )
System.out.println (“A”);
else if (notaEstudante >= 80 )
System.out.println (“B”);
else if (notaEstudante >= 70 )
System.out.println (“C”);
else if (notaEstudante >= 60 )
System.out.println (“D”);
else
System.out.println (“F”);
As duas formas são identicas, exceto quanto ao espaçamento e recuo,
que o compilador ignora.
O problema do else oscilante
O compilado Java sempre associa um else á instrução if imediatamente
anterior, a menos que instruído de outro modo pela colocação de chaves ( { e} ).
Esse comportamento pode levar áquilo que é chamado do Problema do else oscilante.
Por exemplo:
If (x > 5)
If (y > 5)
System.out.println(“x e y são > 5”);
Else
System.out.println(“x é < = 5”);
Parece indicar que se x for maior do que 5, a instrução if aninhada
determina se y também é maior do do que 5. SE for assim, a string “x e y são > 5”
é enviada para a saída. Caso contrário, parece que, se x não for maior que 5, a
parte else do if ...else envia para a saída a string “x é < = 5”.
If (x > 5)
If (y > 5)
System.out.println(“x e y são > 5”);
Else
System.out.println(“x é < = 5”);
Em que o corpo da primeira if é uma if...else aninhada. A instrução if
externa testa se x é maior que 5. Se for, a execução continuará testando se y
também é maior que 5. Se a segunda condição for verdadeira, a string adequada,
“x e y são > 5” é exibida.
Entretanto, se a segunda condição for falsa, a string “ x é < = 5 “ é
exibida, apesar de sabermos que x é maior que 5.
Para forçar a instrução if...else aninhada para executar como foi
originalmente concebida, devemos escreve-la como a seguir:
If (x > 5)
{
if (y.> 5)
System.out.println(“x e y são > 5”);
}
else
System.out.println(“x é < = 5”)
Blocos
A instrução if normalmente espera somente uma instrução no seu corpo.
Para incluir várias instruções no corpo de um if (ou no corpo de um else para uma
instrução if...else), inclua as instruções dentro de chaves ({e}). Um conjunto de
instruções contido dentro de um par de chaves é chamado bloco. Um bloco pode
ser colocado em qualquer lugar em um programa em que uma única instrução
pode ser colocada.
O exemplo abaixo, inclui um bloco na parte do else de uma instrução
if...else.
If ( nota>= 10 )
System.out.println( “Aprovado” );
Else
{
System.out.println( “Reprovado” );
System.out.println( “Você precisa fazer este curso novamente.” );
}
Neste caso se a nota é menor que 10, o programa executa ambas as
instruções no corpo do else e imprime.
Reprovado
Você precisa fazer este curso novamente.
A instrução de repetição while
Uma instrução de repetição (também chamada instrução de loop ou
simplesmente loop) permite ao programador especificar que um programa deve
repetir uma ação enquanto alguma condição permanecer verdadeira.
Enquanto (While) houver mais itens em minha lista de compras
Comprar o próximo item e riscá-lo da minha lista
A instrução de pseudocódigo descreve a repetição que ocorre durante
um passeio de compras. A condição “Enquanto houver mais itens em minha lista
de compras” pode ser verdadeira ou falsa. Se ela for verdadeira, então a ação
“Comprar o próximo item e riscá-lo da minha lista “ é realizada. Essa ação será
realizada repetidamente enquanto a condição permanecer verdadeira. A(s)
instrução(es) contida(s) na instrução de repetição While, pode ser uma única
instrução ou um bloco. Por fim, a condição se tornaria falsa (quando o último item
na lista de compras foi comprado e riscado na lista.) nesse ponto, a repetição
termina e a primeira instrução depois da instrução de repetição é executada.
Como exemplo da instrução de repetição While Java, considere um
segmento de programa projetado para encontrar a primeira potência de 3 maior
que 100. Suponha que a variável int produto tenha sido iniciaizada como 3.
Quando a instrução While seguinte terminar a execução, produto conterá o
resultado.
Int produto = 3;
While ( produto < = 100 )
Produto = 3 * produto;
Quando essa instrução While inicia a execução, o valor de variável
produto é 3. Cada interação da instrução While multiplica produto por 3,assim
produto assume os valores 9, 27, 81 e 243 sucessivamente. Quando a variável
produto torna-se 243, a condição da instrução While – produto < = 100 – torna-se
falsa. Isso termina a repetição, portanto o valor final de produto é 243. Nesse
ponto, a execução de programa continua coma próxima instrução depois da
instrução While.
GUIs e imagens gráficas – Criando desenhos simples.
Um dos recursos Java mais interessantes é seu suporte gráfico que
permite aos programadores aprimorar visualmente seus aplicativos. Nesta lição
introduz uma das capacidades gráficas do Java, desenhar linhas.
Para começar a desenhar em Java, você deve primeiro entender o
sistema de coordenadas do Java, um esquema para identificar cada ponto na
tela. Por padrão o canto superior esquerdo de um componente da GUI tem
coordenadas (o,o). Um par de coordenadas é composto de uma coordenada x (a
coordenada horizontal) e uma coordenada y (a coordenada y (a coordenada
vertical). A coordenada x é a localização horizontal que se estende da esquerda
para a direita. A coordenada y é a localização vertical que se estende de cima
para baixo. O eixo x descreve cada coordenada horizontal e, o eixo y, cada
coordenada vertical.
Aplicativo para criar duas linhas a partir dos cantos.
Na classe Linhas, as instruções import nas linhas 3-4 permitem utilizar a
classe Graphics (do pacote java.awt), que fornece vários métodos para desenhar
texto e formas na tela, e a classe JPanel (do pacote javax.swing) que fornece uma
área em que podemos desenhar.
A linha 6 utiliza a palavra chave extends para indicar que a classe
Linhas é um tipo aprimorado de JPanel. A palavra-chave extends representa o
relacionamento conhecido como herança, no qual nossa nova classe Linhas inicia
com os seus membros existentes (dados e métodos) a partir da classe JPanel. A
classe da qual Linhas Herda, JPanel, aparece à direita da palavra-chave extends.
Nesse relacionamento de herança, JPnel é chamada de Superclasse e linhas é
chamada de Subclasse. Isso resulta em uma classe linhas com os atributos
dados) e comportamentos (métodos) da classe Jpanel.
Todo JPanel, incluindo Linhas, contém um método paintComponent
(linhas 9-22), que o sistema chama automaticamente sempre que precisa exibir o
JPanel. O método paintComponent deve ser declarado como mostrado na linha
9, caso contrário, o sistema não chamará o método. Esse método é chamado
quando um JPanel é exibido na tela pela primeira vez, quando é ocultado e então
exibido por uma janela na tela e quando a janela aparece é redimensionada. O
método paintComponent requer um argumento, um objeto de Graphics, que é
oferecido pelo sistema quando ele chama paintComponent.
A primeira instrução em cada método paintComponent que você cria
sempre deve ser:
super.paintComponent( g );
Isso assegurará que o painel seja adequadamente renderizado na tela
antes de começarmos a desenhar nele. Em seguida, as linhas 14-15 chamam
dois métodos que a classe Linhas herda da classe JPanel. Como Linhas herda da
classe JPanel , a Linhas pode utilizar quaisquer métodos public que são
declarados em JPanel, respectivamente. As linhas 14-15 armazenam esses
valores nas variáveis locais width e heigth. Por fim, as linhas 18 e 21 utilizam
referência g de Graphics para chamar o método drawLine a fim de desenhar as
duas linhas. O método darwLine desenha uma linha entre dois pontos
representados pelos seus quatro argumentos. Os dois primeiros argumentos são
as coordenadas x e y para uma das extremidades da linha, e os dois últimos
argumentos são as coordenadas para a outra extremidade da linha. Se você
redimensionar a janela, as linhas serão dimensionadas da maneira
correspondente uma vez que os argumentos estão baseados na largura e altura
do painel.
Classe de teste do aplicativo.
Aplicativo compilado e já sendo executado.
GUIs e imagens gráficas: Desenhando retângulos e ovais
Para desenhar retângulos e ovais, chamamos métodos Graphics
drawRect e drawOval.
Classe para criar formas.
Após compilar e executar o aplicativo, tecle os comandos para exibir os
retângulos e os ovais.
Ambiente de desenvolvimento – NetBeans
O NetBeans é um projeto open source de sucesso, com uma grande
base de usuários, uma comunidade crescente e perto de 100 parceiros mundiais.
A Sun Microsystems fundou o projeto NetBeans em junho de 2000 e continua
sendo seu principal patrocinador.
A IDE NetBeans é um ambiente de desenvolvimento, uma ferramenta
para programadores, que lhe permite escrever, compilar, debugar e instalar
programas. A IDE é completamente escrita em Java, mas pode suportar qualquer
linguagem de programação. Existe também um grande número de módulos para
estender a IDE NetBeans. A IDE NetBeans é um produto livre, sem restrições de
como ela pode ser usada.
Para iniciar o NetBeans, vá até o menu Iniciar, Todos os Programas,
NetBeans 5.5.1 e selecione NetBeans IDE.
NetBeans iniciado.
Criando um novo projeto na IDE NetBeans.
Criando um nome para o projeto.
Criando a classe principal do projeto.
Altere o caminho de onde será localizado os arquivos de projeto e
finalize.
O corpo de aplicativo será criado.
Para imprimir uma linha de texto, insira o comando:
System.out.println( “Bem Vindo ao NetBeans!!!” );
Par a finalizar a execução, primeiro salve seu aplicativo e logo execute.
Aplicativo compilado e executado.
Na guia Projetos, com o botão direito do mouse, escolha Novo e
selecione Formulário JFrame.
.
Na janela Formulário JFrame, insira o nome da sua classe.
Um desenho é criado na classe Janela.
O Código-Fonte é gerado automaticamente.
Na guia Desenho, visualize a paleta Swing.
Opção JButton inserida ao desenho.
Vários itens da paleta Swing inseridos ao desenho.
Em uma nova classe será criada uma janela simples, insira um JPanel.
Já pode ser visualizada as propriedades do componente JPanel
inserido.
No campo Bordas Disponíveis selecione a opção TitledBorder, e
altere o nome de seu Titulo caso seja necessário.
Ao finalizar a janela de propriedades do titulo, veja o aplicativo alterado.
Inserindo o JLabel
JLabel renomeados.
Os componentes JTextField inseridos logo a frente dos JLabels
Para alterar o tamanho do JTextField, altere a opção preferredSize.
Na janela preferredSize, altere os campos Largura e Altura para os
valores desejados.
Os componentes JTextField ganharam a seguinte forma.
Pode inserir os botões e renomeá-los.
O campo Sexo, pode ser excluído e implementa-lo adicionando o
componente JComboBox.
Selecionando o JComboBox, selecione a opção model.
Na janela model, remova todos os Itens encontrados.
No campo Item acrescente o nome que deseja adicionar.
Finalize a janela model, alteração efetuada.
Para diminuirmos o tamanho do JPanel, selecione-o ou utilize a Paleta
Inspetor.
Arraste a borda para diminuir.
Visualizando a janela.
Para reduzir o tamanho da janela, selecione o JFrame e faça o mesmo
processo do JPanel.
Aplicativo compilado e sendo executado.
Inserindo Ações as Janelas
Adicionando ações à janelas simples.
Interface (janela), aberta no NetBeans.
Selecionando o botão Fechar, botão direito do mouse, Eventos, Action
e actionPerformed.
Código gerado no aplicativo.
.
Logo acima do comentário criado, insira a linha de comando.
Para o botão Limpar, insira as linhas de comando.
Ao botão Somar, insira as linhas de comando.
Arquivo salvo, compilado, sendo executado.
Insira um número no Primeiro Campo e outro no Segundo Campo e
selecione o Somar.
O botão Limpar, apaga todos os valores inseridos.
Arrays
Um array é um grupo de variáveis (elementos ou componentes) que
contém valores que são todos do mesmo tipo. Lembre-se de que os tipos são
divididos em duas categorias, tipos primitivos e tipos por referencia. Os arrays
são objetos, portanto são considerados tipos por referencia. Como você logo verá,
o que e geral consideramos um array é , na verdade, uma referencia a um objeto
de array na memória. Para referenciar um elemento particular em um array,
especificamos o nome da referencia para o array e o número de posição do
elemento no array. O número de posição do elemento é chamado de índice ou
subscrito do elemento.
A figura mostra uma representação lógica de um array de inteiro
chamado c. Esse array contém 12 elementos. Um programa refere-se a qualquer
um desses elementos com uma expressão de acesso ao array que inclui o
nome array seguido pelo índice do elemento particular entre colchetes ( [ ] ). O
primeiro elemento em cada array tem indice zero e às vezes é chamado de zeroésimo elemento. Portanto, os elementos do array c são c [0], c [1], c [2] e assim
por diante. O índice mais alto do array c é 11, que é 1 menor que 12, o número de
elementos no array. Nomes de array seguem as mesmas convenções que outros
nomes de variável.
Um índice deve ser um inteiro não-negativo. Um programa pode utilizar
uma expressão como um índice. Por exemplo, se assumimos que variável a é 5 e
a variável b, 6, então a instrução adiciona 2 ao elemento do array c [ 11 ].
soma = c [ 0 ] + c [ 1 ] + c [ 2 ];
Para dividir o valor de c [ 6 ] por 2 e atribuir o resultado à variável x,
escreveríamos.
X = c [ 6 ] / 2;
Declarando e criando arrays
Os objetos de array ocupam espaço na memória. Como os outros
objetos, os arrays são criados com a palavra-chave new. Para criar um objeto
array, o programador especifica o tipo dos elementos do array e o número de
elementos como parte de uma expressão de criação de array que utiliza a
palavra-chave new. Tal expressão retorna uma referência que pode ser
armazenada em uma variável array. A declaração e a expressão de criação de
arrays a seguir criam um objeto array que contém 12 elementos int e armazenam
a referência do array na variável c:
int c [ ] = new int [12 ];
Essa tarefa também pode ser realizada em dois passos, veja abaixo:
int c [ ] ;
//declara a variável array
c = new int [ 12 ]; // cria o array; atribui à variável array
Na declaração, os colchetes que seguem o nome da variável c indicam
que c é uma variável que referenciará um array ( isto é, a variável armazenará
uma referência de array). Na instrução de atribuição, a variável array c recebe a
referência para um novo array de 12 elementos int. Quando um array é criado,
cada elemento do array recebe um valor padrão, zero para os elementos
numéricos de tipo primitivo, false para elementos bool e null para referências
(qualquer tipo não primitivo).
Um programa pode criar vários arrays em uma unica declaração. A
declaração de String de array a seguir reserva 100 elementos para b e 27
elementos para x:
String b [ ] = new String [ 100 ], x [ ] = new String [ 27 ];
Nesse caso, o nome de classe String aplica –se a cada variável na
declaração. Para legibilidade, preferimos declarar apenas uma variável por
declaração, como em:
String b [ ] = new String [100]; //cria array b
String x [ ] = new String [ 27] ; //cria array x
Um programa pode declarar arrays de qualquer tipo. Cada elemento de
um array de tipo primitivo contém um valor do tipo declarado do array. De
maneira semelhante, em um array de um tipo por referência, todo elemento é uma
referência a um objeto do tipo declarado do array. Por exemplo, todo elemento de
um array int é um valor int e todo elemento de um array String é uma referência a
um objeto String.
Exemplo que utilizam arrays
Criando e inicializando um array
A linha 8 declara array, uma referência capaz de referenciar um array de
elementos int. A linha 10 cria o objeto array e atribui sua referência à variável
array. A linha 12 gera saída dos títulos de coluna. A primeira coluna contém o
índice (0-9) de cada elemento do array e a segunda coluna contém o valor padrão
(0) de cada elemento array.
A instrução for nas linhas 15-16 gera saída do número de índice
(representado por counter) e valor de cada elemento de array (representado por
array [counter]). Observe que a variável de controle loop counter é inicialmente 0,
os valores de índice iniciam em 0, então utilizar a contagem baseada em zero
permite ao loop acessar cada elemento do array. A condição de continuação do
loop for utiliza a expressão array.length (linha 15) para determinar o comprimento
do array. Em nosso aplicativo, o comprimento do array é 10, então o loop
continua a executar enquanto o valor da variável de controle counter for menor
que 10. O valor de índice mais alto de um array de 10 elementos é 9, portanto
utilizar o operador menor que na condição de continuação do loop garante que o
loop não tentará acessar um elemento alem do fim do array (isto é, durante a
iteração final do loop, counter é 9).
Aplicativo executado.
Utilizar um inicializador de array
Um programa pode criar um array e iniciar seus elementos com um
inicializador de array, que é uma lista de expressões separadas por virgulas
(chamadas de lista de inicializadores) colocadas entre chaves ( { e } ). Nesse
caso, o comprimento do array é determinado pelo número de elementos na lista
inicializadora. Por exemplo, a declaração:
int n [ ] = { 10, 20, 30, 40, 50 };
Cria um array de cinco elementos com os valores de índice 0, 1, 2, 3, 4.
O elemento n [ 0 ] é inicializado como 10, n [1] é inicializado como 20 e assim por
diante. Essa declaração não requer new para criar o objeto array. Quando o
compilador encontrar uma declaração de array que inclua uma lista de
inicializadores, o compilador conta o número de inicializadores na lista para
determinar o tamanho do array, depois configura a operação new apropriada “nos
bastidores”.
Tratamento de exceção
Uma exceção é uma indicação de um problema que ocorre durante a
execução de um programa. O nome ”exceção” dá a entender que o problema
ocorre raramente, se a ”regra” é que uma instrução execute geralmente de modo
correto, então a “exceção à regra” é que um problema ocorra. O tratamento de
exceções permite aos programadores criar aplicativos que podem resolver (ou
tratar) exceções. Em muitos casos, o tratamento de uma exceção permite que um
programa continue executando como se nenhum problema tivesse sido
encontrado. Um problema mais grave poderia impedir o programa de continuar
executando normalmente, em vez de requerer que o problema seja informado
antes de encerrar de uma maneira controlada. Os recursos que serão
apresentados nesta lição permitem que os programadores escrevam programas
robustos e tolerantes a falhas, isto é, programas que sejam capazes de lidar
com possíveis problemas e continuar executando.
Visão geral do tratamento de exceções
Os programas costumam testar condições para determinar como a
execução do programa deve prosseguir. Considere o seguinte pseudocódigo:
Realize uma tarefa
Se a tarefa anterior não tiver sido executada corretamente
Realize processamento de erro
Realize a próxima tarefa
Se a tarefa anterior não tiver sido executada corretamente
Realize processamento de erro
...
Nesse pseudocódigo, começamos realizando uma tarefa; depois
testamos se essa tarefa foi executada corretamente. Se não tiver sido, realizamos
processamento de erro. Caso contrário continua com a próxima tarefa. Embora
essa forma de tratamento de erro funcione, mesclar o programa com a lógica de
tratamento de erro pode dificultar a leitura, a modificação, a manutenção e a
depuração dos programas, especialmente em aplicativos grandes.
Exemplo de um tratamento de exceção, utilizando a classe DivideZero.
Aplicativo executado.
Campo Entrada, com um número inteiro adicionado.
Para adicionar o número inteiro, tecle <Enter>, insira o denominador,
pressione <Enter> e o resultado será obtido.
Caso o usuário entre com um número inteiro invalido, será obtido o
seguinte erro.
Se o usuário entrar com uma palavra, o erro será o seguinte.
Nas execuções, quando as exceções ocorrem e rastreamentos de pilha
são exibidos, o programa também se fecha. Isso nem sempre ocorre em Java, às
vezes um programa pode continuar mesmo que uma exceção tenha ocorrido e um
rastreamento de pilha tenha sido impresso. Nesses casos, o aplicativo pode
produzir resultados inesperados.
Tratando ArithmeticExceptions e InputMismatchExceptions
A classe DivideZero1.java, utiliza o tratamento de exceções para
processar quaisquer ArithmeticExceptions e InputMismatchExceprions que
possam surgir.
Neste aplicativo, quando executado, caso o usuário insira um valor
inteiro não valido, o mesmo irá permitir que o usuário tente novamente.
O mesmo procedimento será feito, caso o usuário digite uma palavra.
Recursão
Conceitos de recursão
Abordagens de solução de problemas de recursão têm um número de
elementos em comum. Quando um método recursivo é chamado para resolver um
problema, na realidade o método é capaz de resolver apenas os casos mais
simples ou os casos básicos. Se a chamada de método for com um caso básico,
o método retorna um resultado. Se o método for chamado com um problema mais
complexo, em geral o método divide o problema em duas partes conceituais, uma
parte que o método sabe como fazer e outra que o método não sabe fazer. Para
tornar a recursão realizável, a ultima parte deve assemelhar-se ao problema
original, o método chama uma cópia dele próprio para trabalhar no problema
menor, isso é referido como chamada recursiva e também passo de recursão.
O passo de recursão normalmente inclui a instrução return, uma vez que seu
resultado será combinado com a parte do problema que o método sabia como
resolver para formar um resultado que será passado de volta para o chamador
original.
Um método recursivo pode chamar outro método, que por sua vez pode
fazer uma chama de volta ao método recursivo. Tal processo é conhecido como
chamada recursiva indireta ou recursão indireta. Por exemplo, o método A
chama o método B, que faz uma chamada de volta ao método A. Isso ainda é
considerado recursão, porque a segunda chamada para o método A é feita
enquanto a primeira chamada ao método A está ativa, isto é, a primeira chamada
ao método A ainda não concluiu sua execução (porque está esperando o método
B retornar um resultado para i) e não retornou ao chamador original o método A.
Recursão Fatorial
Considere o fatorial de um inteiro positivo n, escrito n! (e pronunciado
como “n fatorial”), que é produto.
n • (n – 1) • (n – 2) •...•1
O valor de 1! pode ser diferido com 1 ou 0!. Por exemplo, 5! É o produto
de 5•4•3•2•1, que é igual a 120.
O fatorial de inteiro numero(onde numero >= 0 ) pode ser calculado
iterativamente (não recursivamente) utilizando uma instrução for como a
seguinte: fatorial = 1;
for (int contador = numero; contador >= ; contador - -)
fatorial *= contador;
Chega-se a uma declaração recursiva de método fatorial observando o
seguinte relacionamento:
n! = n • (n-1)!
Por exemplo, 5! é claramente igual a 5 • 4!, como mostrado pelas
seguintes equações:
5! = 5•4•3•2•1
5! = 5 •(4•3•2•1)
5! = 5 • (4!)
Utilizando recursão na classe CalcularFatorial.java.
O aplicativo utiliza a recursão para calcular e imprimir os fatoriais dos
inteiros de 0-10. O método recursivo fatorial (linhas 7-13) primeiro testa para
determinar se uma condição de término (linha 9) é true. Se numero for menor que
ou igual a 1 (o caso básico), fatorial retorna 1, nenhuma recursão adicional é
necessária e o método retorna. Se numero for maior que 1, a linha 12 expressa o
problema como o produto de um numero e uma chamada recursiva para fatorial
avaliando o fatorial de numero – 1, que é um problema ligeiramente mais simples
que o cálculo original, fatorial (numero).
O método displayFatoriais linhas 16-21) exibe o fatorial de 0-10. A
chamada para o método fatorial ocorre na linha 20. O método fatorial recebe um
parâmetro de tipo long. A próxima classe que vamos criar será a classe de teste
que irá testar o nosso fatorial e métodos displayFatoriais chamando
displayFatoriais.
Classe de teste, contendo o método main.
A partir do aplicativo da classe teste, os valores fatoriais tornam-se
rapidamente grandes. Utilizamos o tipo long (que pode representar inteiros
relativamente grandes) para que o programa possa calcular fatoriais maiores qu
12!. Infelizmente, o método fatorial produz valores grandes tão rapidamente que
os valores fatoriais logo excedem o valor máximo que pode ser armazenado
mesmo em uma variável long.
Aplicativo compilado e executado.
Dica*: O Java é uma linguagem extensível que permite criar inteiros
arbitrariamente grandes se quisermos.
Permutações de string
O problema que analisamos é a criação de permutações de uma string
de texto, todas as strings diferentes que podem ser criadas pela reorganização
doa caracteres da string original. As palavras criadas a partir dessas strings são
conhecidas como anagramas. As permutações para a string “abc” são:
abc
acb
bac
bca
cab
cba
Um programa como esse poderia ser útil se alguém quiser
desembaralhar uma string de caracteres, determinar todas as palavras que podem
ser criadas a partir de uma string ou determinar todas as palavras que podem ser
criadas a partir dos caracteres associados com número de telefone.
Na lista precedente de permutações, observe que duas das
permutações resultantes iniciam com “a” (“abc” e “acb”), duas com “b” (“bac” e
“bca”) e duas com “c” (“cab” e “cba”). Para cada letra, as permutações são desde
que iniciem com essa letra, seguidas por permutações das letras restantes. Se
fosse começar com a letra “b”, por exemplo, teríamos duas permutações, “bac” e
“bca”. Essas são determinadas simplesmente examinando as duas letras
restantes, “a” e “c”, e verificando que há apenas duas permutações que utilizam
essas letras, a saber, “ac” e “ca”. Observe que agora acabamos de determinar
todas as permutações na string menor, “ac”. Para fazer isso, podemos utilizar o
mesmo processo de raciocínio anterior, isto é, determinando todas as
permutações que iniciam com a letra “a” seguidas de todas as permutações que
iniciam com a letra “c”. Se iniciarmos com a letra “a”, restará apenas a letra “c”.
Para uma string com apenas um caractere, a próxima string é a única permutação.
Classe utilizando permutações de string.
O método permuteString (linhas 7-38) aceita dois argumentos. O
primeiro, beginningString, contém os caracteres que forma removidos da string
nas chamadas anteriores e agora precisa proceder as permutações que estão
sendo criadas. O segundo argumento, endingString, contém a string que precisa
ser permutada (denominamos essa string endingString porque para nossos
resultados finais ela será exibida depois de beginningString). Quando o método é
chamado com a string original, o primeiro argumento será a string vazia, uma vez
que não há caracteres de chamadas anteriores que precisam ser adicionados à
solução. O caso básico ocorre nas linhas 12-13, quando a string permutada
contém apenas um caractere. Nesse caso, simplesmente imprimimos os
caracteres de chamadas anteriores (beginningString) seguidos pelo caractere em
endingString.
O passo de recursão ocorre nas linhas 14-37. A instrução for faz uam
chamada recursiva para cada uma das substrings. O caractere atual removido é o
caractere retornado de endingString.charAt( i ). O método charAt aceita um
argumento de inteiro e retorna o caractere na string naquele índice. Como com os
arrays, considera-se que o primeiro elemento de uma string está na posição 0. A
instrução for intera através de cada caractere em endingString, de modo que as
permutações que serão criadas iniciem com cada letra em endingString.
Para criar a substring que precisa ser permutada, o caractere no índice i
deve ser removido da string que será passada na chamada recursiva. Para
remover um caractere, concatenamos duas substrings, a primeira contém todos os
caracteres que ocorrem antes do caractere removido e a segunda substring
contém parte da string que ocorre depois de o caractere ser removido. Por
exemplo, para remover o caractere “s” da palavra “recursion”, criamos a nova
string concatenando a primeira substring, “recur”, com “íon”, resultando em
“recurion”. As linhas 23-24 criam essa substring que utiliza o método String
substring. A classe String fornece dois métodos substring para retornar um novo
objeto String criado copiando parte de um objeto String existente. A chamada na
linha 23 passa ao método substring dois inteiros ( 0 e i ). O primeiro argumento
especifica o índice inicial na string original da qual os caracteres são copiados. O
segundo argumento especifica o índice um alem do ultimo caractere que será
copiado (isto é, copiar, mas não incluir, esse índice na string). A substring
retornada contém copias do intervalo especificado de caracteres da string original.
Portanto, a chamada do método na linha 23 retorna todos os caracteres desde o
começo de endingString, mas não inclui o caractere no índice i ( o caractere que
estamos tentando remover). Se os argumentos estiverem fora dos limites da
string, o programa gera uma StringIndexOutOfBoundException (tratadas nas
linhas 32-35).
As linhas 29-30 realizam a chamada recursiva. O primeiro argumento
passado é beginningString concatenado com endingString.charAt( i ). Dessa
maneira, combinamos os caracteres isolados das chamadas anteriores
(beginningString) como o caractere isolado nessa chamada. O segundo
argumento é newString, que é a substring a ser permutada.
Classe de teste do aplicativo, testando o método recursivo.
A linha 9 cria um objeto Scanner para ler uma string do teclado. A linha
10 cria um objeto Permutacao com o qual se chama o método permuteString. A
string é lida na linha 13 e passada para o método permuteString na linha 16.
Observe que essa chamada fornece uma string vazia como primeiro argumento e
a string a permutar como
segundo argumento. Como
ainda não removemos nenhum
caractere
da
string,
beginningString (o primeiro
argumento) deve ser uma
string
vazia.
Alguns
programadores podem querer
definir o método permuteString
como private e criar outro
método public que aceita
somente a string a ser
permutada.
Esse
método
poderia
então
chamar
permuteString com a string
vazia
como
no
primeiro
argumento e a string a ser
´permutada como segundo
argumento. Isso asseguraria
que o usuário não inserisse
algo diferente da string vazia
no primeiro argumento no
método permuteString.
As permutações serão impressas no prompt de comando. Observe que,
se uma string for inserida com caracteres repetidos, cada caractere é tratado
individualmente, resultando em permutações repetidas.
Dica*: pode-se inserir outras palavras para verificar as permutações.
Download