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.