Você está na página 1de 61

Programao JAVA

Joacir Giaretta

joacir@abacus.inf.br

Introduo
Tendo sido originalmente concebida para o desenvolvimento de pequenos aplicativos e programas de controle de aparelhos eletrodomsticos e eletroeletrnicos, Java mostrou-se ideal para ser usada na rede Internet. O que a torna to atraente o fato de programas escritos em Java poderem ser executados virtualmente em qualquer plataforma, seja para computadores desktops, como Windows, Linux, Mac, seja para smartphones e celulares, como Symbian, Android, BlackBarry, seja para sistemas operacionais proprietrios, sistemas embarcados. Java uma linguagem de programao orientada a objeto desenvolvida na dcada de 90 por uma equipe de programadores chefiada por James Gosling, na empresa Sun Microsystems. Diferentemente das linguagens convencionais, que so compiladas para cdigo nativo, a linguagem Java compilada para um bytecode que executado por uma mquina virtual. Java possui estrutura muito semelhante da linguagem C, da qual descende imediatamente. Java tem em comum com a linguagem C++ o fato de ser orientada a objetos e mantm com esta uma alto grau de semelhana. Esse paradigma de programao consiste de um grau a mais na abstrao da programao, em comparao com a programao estruturada, e tem se mostrado extremamente til na produo de programas cada vez mais sofisticados, em menor tempo e com maior qualidade. A programao orientada a objetos (OOP) hoje universalmente adotada como padro de mercado, e muitas linguagens tradicionais foram aperfeioadas para implementar esse paradigma, como C++, Object Pascal, etc. A Sun Microsystems foi a desenvolvedora da linguagem Java at que, em Abril de 2009, a Oracle a comprou, sendo atualmente a detentora dos direitos autorais. O site http://java.sun.com continua sendo o site oficial e mantm informaes atualizadas sobre o desenvolvimento da linguagem Java e suas relaes com o mercado, assim como utilitrios e ferramentas disponveis para serem baixados gratuitamente.

Como Java executado


Um cdigo fonte escrito em linguagem Java (.java) traduzido pelo compilador para os bytecodes (.class), isto , o cdigo de mquina de um processador virtual, chamado Java Virtual Machine (JVM). A JVM um capaz de interpretar os bytecodes produzidos pelo compilador, executando a aplicao vrias vezes mais lento do que linguagens com cdigo executvel nativo da plataforma. Em contrapartida, uma aplicao Java pode ser executada em qualquer plataforma, desde que esteja dotada de uma JVM. 1

Ambientes de Desenvolvimento
possvel desenvolver aplicaes em Java atravs de vrios ambientes de desenvolvimento integrado (IDEs). Dentre as opes mais utilizadas pode-se destacar algumas para usurios iniciantes:

BlueJ um ambiente desenvolvido por uma faculdade australiana (considerado muito bom para iniciantes); JCreator (gratuito/shareware) um ambiente desenvolvido pela Xinox (recomendado para programadores iniciantes); jEdit (recomendado para programadores iniciantes);

E outras IDEs mais completas (recomendado para programadores profissionais):


Eclipse (software livre) um projeto aberto iniciado pela IBM; IntelliJ IDEA (comercial) uma IDE desenvolvida pela JetBrains; JBuilder um ambiente desenvolvido pela empresa Borland; JDeveloper (gratuito OTN) uma IDE desenvolvida pela empresa Oracle; NetBeans (software livre) uma IDE desenvolvida pela Sun Microsystems;

Por serem gratuitas, o Eclipse (www.eclipse.org) e o NetBeans (www.netbeans.org) so IDEs muito utilizadas, tanto a nvel acadmico como profissional. Essas sero as ferramentas escolhidas para trabalhar com essa apostila.

Antes de instalar uma dessas ferramentas, fundamental baixar e instalar o JDK (Kit de Desenvolvimento Java) mais atual possvel, encontrado em http://java.sun.com. Esse JDK especfico para a plataforma que se quer desenvolver. Por exemplo:

Java SE (Standard Edition): a base da plataforma Java e utilizada para desenvolver aplicativos desktops e servidores. Java EE (Enterprise Edition): Necessria para desenvolver softwares que rodam em servidores de aplicaes (geralmente aplicaes web). Java ME (Micro Edition): Utilizada para desenvolver softwares para dispositivos mveis e para dispositivos com pouca capacidade de processamento, como por exemplo: telefones celulares.

Para o contedo dessa apostila, iremos utilizar o Java SE. necessrio esclarecer duas siglas: JRE (Java Runtime Environment): composto pela JVM e pela biblioteca de classes Java utilizadas para execuo de aplicaes java, estas bibliotecas so chamadas de APIs Java. Portanto, para rodarmos uma aplicao Java necessrio instalarmos uma JRE no computador onde o software foi instalado. JDK (Java Development Kit): o conjunto de ferramentas necessrias para realizar o desenvolvimento de aplicaes Java e inclui a JRE e ferramentas de programao. Esse o que deve ser baixado e instalado para a continuidade dessa apostila.

No momento da digitao dessa apostila, a verso do Java SE estava na Java SE 6 Update 25, e com indicativos de lanamento do Java SE 7. importante que se tenha a JDK sempre atualizada, pois as atualizaes so feitas constantemente pelos programadores do Java. Para instalar uma nova verso, v no Painel de Controle e remova a verso anterior, caso contrrio ela ficar instalada juntamente com a nova, o que no uma boa ideia.

Programao Bsica
Vamos iniciar com o clssico "Al pessoal!". O objetivo desta classe (estilo aplicao) simplesmente escrever na tela a frase "Al pessoal!". Vejamos como o cdigo fonte:
public class AloPessoal { public static void main(String args[]) { System.out.println("Alo pessoal!"); } }

Digitando e executando a classe


Vamos fazer trs testes com a mesma classe: 1) Crie uma workspace no Eclipse, chamada WSEclipse. Lembre-se que o Eclipse abre os projetos a partir de uma workspace. No possvel abrir um projeto diretamente, sempre necessrio abrir a workspace. Aps abri-la, crie um projeto chamado Projeto Aula 3

Java.

A seguir, crie um pacote chamado principal (em minsculo, pois, por conveno Java, pacotes so escritos sem nenhuma maiscula). Por fim, crie a classe AloPessoal, clicando no checkbox para inserir o main() automaticamente. Ento, digite o println e execute com o auxlio das teclas Ctrl + F11. 2) Crie um projeto no NetBeans (o NetBeans no trabalha com workspaces) chamado Projeto Aula Java. A seguir, crie um pacote chamado principal. Por fim, crie a classe AloPessoal (o NetBeans no possui checkbox para inserir o main() automaticamente). Ento, adicione o main(), digite o println e execute com o auxlio das teclas Shift + F6. 3) Apenas a ttulo de conhecimento, no necessrio ter uma IDE para executar aplicaes Java. Ento, vamos utilizar o Bloco de Notas para criar o arquivo AloPessoal.java. O nome do arquivo deve ser exatamente igual ao nome da classe. Digite a classe dentro desse arquivo e salve-a. Para compilar, vamos para o Prompt de Comando, direcionando para a pasta onde foi salvo o arquivo (cd \pasta). D um dir para verificar se o arquivo est nessa pasta. Aps, digite javac AloPessoal.java. O javac o compilador Java e, se tudo der certo, ir gerar o arquivo AloPessoal.class, que o bytecode, que pode ser executado a partir do comando java AloPessoal.

Entendendo a estrutura do programa


Toda classe auto-executvel Java deve conter ao menos uma declarao da forma
public class [nome] { public static void main(String args[]) { ... } }

Onde [nome] o nome da classe e a parte "..." o cdigo Java vlido, a ser executado no programa. O nome de uma classe um identificador, como qualquer outro presente no programa, por isso no deve conter espaos ou outros caracteres grficos, isto , deve ser um nome composto de uma sequncia de caracteres que seja vlida para um identificador. Outros exemplos de identificadores so nomes de variveis, nomes de comandos, etc. Vamos adiar um pouco a complicao sobre o que vem a ser uma classe, pois isso depende de alguns conceitos da programao orientada a objetos. Por hora, vamos apenas aceitar que toda aplicao Java deve conter ao menos uma classe, e que dentro de uma classe que vo os dados e as funes. Notemos ainda que toda classe estilo aplicao Java deve ter uma classe dotada de uma funo chamada main(). As funes, na Orientao a Objetos, levam o nome de mtodos. O mtodo main() o ponto onde se d o incio da execuo do programa, isto , um mtodo chamado automaticamente pela JVM. Voltando classe AloPessoal, o cdigo a ser executado
System.out.println("Alo pessoal!");

o nome de um mtodo que serve para escrever informaes textuais na tela. Note que existe um ; (ponto e vrgula) no final da linha, logo aps o ")". Em Java, obrigatrio colocar um ponto e vrgula aps cada comando, bem semelhante a Linguagem C.
System.out.println

Mais exemplos
Podemos escrever "Alo pessoal!" escrevendo primeiro, "Alo " e depois, "pessoal!". Para isso, a classe deve ser alterada da seguinte forma:
public class Alo { public static void main(String args[]) { System.out.print("Alo "); System.out.println("pessoal!"); } }

Para escrever dados genricos na tela, existe o System.out.print que escreve o dado e mantm o cursor na mesma linha. H tambm o System.out.println que escreve dados e muda o cursor para a prxima linha. Podemos concatenar dois ou mais strings usando o operador de concatenao "+". Por exemplo,
"Alo " + "pessoal!"

o mesmo que "Alo pessoal!". Para escrever um nmero, basta escrever [string]+n onde [string] uma string qualquer e n um nmero. Vamos utilizar um exemplo declarando variveis inteiras, somando-as e mostrando o resultado:
public class Numero { public static void main(String args[]) { int a = 3, b = 2, c; c = a + b; System.out.println("A soma de " + a + " com " + b + " resulta " + c); } }

A converso das variveis numricas para String feita automaticamente pelo operador de concatenao. E ele entende que no uma soma porque comea com um String ( "A soma de"). Compilando e executando esse exemplo, devemos obter na tela:
A soma de 3 com 2 resulta 5

Introduzindo comentrios no cdigo


Um comentrio uma poro de texto que no tem funo para o compilador Java, mas til para identificar partes de cdigo de programao. Assim sendo, um comentrio identificado, mas ignorado completamente pelo compilador Java. Os comentrios so introduzidos no cdigo Java de duas formas distintas (semelhante a linguagem C):

Colocado em qualquer parte da classe e delimitado entre /* e */. Colocado // antes do comentrio, que se estender at o final da linha. 5

Por exemplo, o cdigo:


// // Este um exemplo de como somar dois numeros // public class Numero { public static void main(String args[]) { /* Mtodo principal */ double x,y; // estes sao numeros reais de dupla precisao // System.out.print("x = 2.0"); /* inicializando o "x" */ x = 2; y = 3.0; /* iniciando o y, e fazendo y = y+x; */ y = y + x; // escrevendo a soma System.out.println("x+y = " + (x+y)); } } /* fim de Numero */

equivalente ao cdigo:
public class Numero { public static void main(String args[]) { double x,y; x = 2; y = 3.0; } y = y + x;

System.out.println("x+y = " + (x+y)); }

No prximo captulo, vamos estudar detalhadamente os tipos de dados aceitos pela linguagem Java.

Tipos de Dados
Programao de computadores consiste essencialmente em manipulao de dados. Os dados representados em um computador podem ser de diversos tipos, e eles so classificados conforme esses tipos. Por isso, damos o nome de Tipos de Dados. A linguagem Java oferece diversos tipos de dados com os quais podemos trabalhar. Este captulo cobrir os tipos de dados mais importantes. Na verdade h basicamente duas categorias em que se encaixam os tipos de dados: tipos primitivos e tipos de referncias. Os tipos primitivos correspondem a dados mais simples ou escalares e sero abordados em detalhe no que segue, enquanto os tipos de referncias consistem em arrays, classes e interfaces. Estes sero vistos posteriormente. Descrio boolean Pode assumir o valor true ou o valor false. Utiliza um nico bit na memria. Caractere em notao Unicode (www.unicode.org) de 16 bits. Serve para a char armazenagem de dados alfanumricos. Tambm pode ser usado como um dado inteiro com valores na faixa entre 0 e 65535. Inteiro de 8 bits em notao de complemento de dois. Pode assumir valores entre byte -27=-128 e 27-1=127. 6 Tipo

Inteiro de 16 bits em notao de complemento de dois. Os valores possveis cobrem a faixa de -2-15=-32.768 a 215-1=32.767 Inteiro de 32 bits em notao de complemento de dois. Pode assumir valores entre int -231=2.147.483.648 e 231-1=2.147.483.647. Inteiro de 64 bits em notao de complemento de dois. Pode assumir valores entre long -263 e 263-1. Representa nmeros em notao de ponto flutuante normalizada em preciso simples de 32 bits em conformidade com a norma IEEE 754-1985. O menor valor float positivo representvel por esse tipo 1.40239846e-46 e o maior 3.40282347e+38 Representa nmeros em notao de ponto flutuante normalizada em preciso dupla de 64 bits em conformidade com a norma IEEE 754-1985. O menor valor double positivo representvel 4.94065645841246544e-324 e o maior 1.7976931348623157e+308
short

Atribuio de Dados e Identificadores


Para exemplificar os tipos de dados, faremos atribuies a partir do operador de atribuio "=", que indica o valor que a varivel receber: 1. 2. 3. 4. Informar o tipo de dado que deseja declarar (boolean, int, etc) Informar o nome que ser usado para batizar a varivel (somaTotal, por exemplo) Atribuir varivel um valor inicial. Terminar a declarao com um ponto-e-vrgula ";".

Exemplo: int somaTotal = 15; ou:


int somaTotal; somaTotal = 15;

Na declarao acima usamos o nome somaTotal para designar a varivel. Um nome de varivel, assim como nome de um mtodo, classe, rtulo e dezenas de outros itens lexicogrficos, constitui o que chamado um identificador. Uma vez criado, um identificador representa sempre o mesmo objeto a ele associado, em qualquer contexto em que seja empregado. As seguintes regras orientam a criao de identificadores:

O primeiro caracter de um identificador deve ser uma letra. Os demais caracteres podem ser quaisquer sequncias de nmeros e letras. Devido a razes histricas, o underline "_" e o sinal de dlar "$" so considerados letras e podem ser usados nos identificadores. Assim como em outras linguagens, como C e C++, os identificadores distinguem o tipo de caixa das letras, isto , as maisculas so consideradas distintas das minsculas. H uma conveno Java que regulamente a utilizao disso: 7

Variveis e Mtodos: primeira inicial minscula e demais maisculas. Ex: fimDeArquivo, meuMetodo() Classes: todas iniciais maisculas. Ex: AloPessoal Pacotes todas iniciais minsculas. Ex: pacoteprincipal

Tipo caracter
Uma varivel do tipo char armazena um caractere Unicode. Um caractere Unicode um caractere de 16 bits, sendo que de 0 a 225 correspondem aos caracteres do cdigo ASCII (a tabela ASCII uma tabela padronizada internacionalmente de associaes entre caractere e a sua representao numrica no computador). Uma constante do tipo caractere representada colocando-se entre apstrofos, ou pelo valor numrico correspondente na tabela Unicode (ou ASCII), ou ainda, pela seqncia '\x' onde x especifica o caractere a ser referido. Esta especificao de seqncia de escape obedece s mesmas convenes do C/C++. Por exemplo: 'a', 'f', '\n', etc, so constantes do tipo char. Exemplo de caracteres especiais:
Representao visual: Funo, significado: \n Pula linha, linefeed \r Retorno de carro \b Backspace \ Apstrofe \ Aspas \\ Barra inversa

Exemplo:
char letra = 'A' ; char letra2 = 65 ; // na tabela ASCII o 65 corresponde ao 'A'

Tipo Boolean
Este o tipo de dado mais simples encontrado em Java. Uma varivel booleana pode assumir apenas um entre dois valores: true ou false. Algumas operaes possveis em Java como a<=b, x>y, etc. tm como resultado um valor booleano, que pode ser armazenado para uso futuro em variveis booleanas. Estas operaes so chamadas operaes lgicas. As variveis booleanas so tipicamente empregadas para sinalizar alguma condio ou a ocorrncia de algum evento em uma aplicao Java. Exemplo:
boolean fimDoArquivo = false;

Tipos de Dados Inteiros


Os tipos de dados primitivos byte, int, char, short e long constituem tipos de dados inteiros. Isso porque variveis desses tipos podem conter um valor numrico inteiro dentro da faixa 8

estabelecida para cada tipo individual. Por exemplo, um byte pode conter um inteiro entre -128 e 127, enquanto um short pode conter um valor entre -32.768 e 32.767. J o tipo long permite armazenar valores muito maiores. H diversas razes para se utilizar um ou outro dos tipos inteiros em uma aplicao. Em geral, no sensato declarar todas as variveis inteiras da aplicao como long. Raramente os programas necessitam trabalhar com dados inteiros que permitam fazer uso da mxima capacidade de armazenagem de um long. Alm disso, variveis grandes consomem mais memria do que variveis menores, como short. Exemplo:
byte Contador = 1; int AnguloEmGraus = -45; char Indice = 6;

A diferena entre essas declaraes e a declarao de dados booleanos vista acima est no tipo de dado especificado e no valor atribudo a cada varivel.

Operaes com inteiros


Podemos realizar uma srie de operaes com os dados do tipo inteiro. A tabela seguinte mostra uma lista completa. Operao
= ==, !=

Descrio

Operador de atribuio Operadores de igualdade e diferena <, <=, >, >= Operadores de desigualdade +, Operadores unrios +, -, *, /, % Adio, subtrao, multiplicao, diviso e mdulo Operadores de atribuio com adio, subtrao, multiplicao, diviso e +=, -=, *=, /=, %= mdulo ++, -Incremento e decremento <<, >>, >>> Operadores de deslocamento de bits <<=, >>=, >>>= Operadores de atribuio com deslocamento de bits ~ Operador lgico de negao &, |, ^ Operadores lgicos E, OU e OU-exclusivo &=, |=, ^= Operadores de atribuio com operao lgica E, OU e OU-exclusivo Muitas das operaes que aparecem na lista acima so familiares e praticamente no requerem explicao. H outros, porm, que podem simplificar, ou deixar mais compacta a programao. o caso dos operadores de atribuio aritmticos. Estes consistem de atalhos para atribuir um novo valor a uma varivel onde esse novo valor depende do valor anterior l armazenado. Por exemplo: += adiciona um valor ao valor antigo de uma varivel e a soma passa a ser o novo valor. Esse padro tambm obedecido para as operaes -=, *=, /= e %=. Temos assim as seguintes correspondncias: 9

x x x z

+= -= *= /=

5 y 2 4

x x x z

= = = =

x x x z

+ * /

5 y 2 4

Os operadores de incremento e decremento referem-se a apenas uma varivel (logo so chamados de unrios). Por exemplo, o operador de incremento soma um ao operando conforme o exemplo:
x++;

uma maneira muito mais concisa de se escrever x = x + 1. Mas no s, esses operadores se comportam de modo diferente quando seguem ou precedem o nome de uma varivel. Se o operador precede o nome da varivel, ento o incremento (ou decremento) ocorre antes que o valor da varivel seja tomado para a expresso aritmtica. No seguinte exemplo, o valor das variveis x e y ser 6:
int x = 5; int y = ++x;

Porm, no prximo exemplo o valor de x ser 6 enquanto que o valor de y ser 5:


int x = 5; int y = x++;

Vejamos alguns exemplos de declaraes e de utilizaes de operaes envolvendo tipos inteiros:


byte j = 60; short k = 24; int l = 30; long m = 12; long n = 9223372036854775807L; long resultado = 0L; resultado += j; // resultado = 60 (0 mais 60) System.out.println("Resultado = " + resultado); resultado += k; // resultado = 84 (60 mais 24) System.out.println("Resultado = " + resultado); resultado /= m; // resultado = 7 (84 dividido por 12) System.out.println("Resultado = " + resultado); resultado -= l; // resultado = -23(7 menos 30) System.out.println("Resultado = " + resultado); resultado = -resultado; // resultado = 23 ( -(-23) ) System.out.println("Resultado = " + resultado); resultado %= m; // resultado = 11 (resto de 23 div. 12) System.out.println("Resultado = " + resultado);

Qualquer literal inteiro considerado do tipo int. Por exemplo, o nmero 4 considerado um int, mas pode ser atribudo s variveis byte e short, pois o nmero suficientemente pequeno para caber nesses tipos de inteiro. Se for feita a atribuio desse mesmo nmero para uma varivel long, tambm ser possvel, porm, se o nmero inteiro atribudo for maior que 2147483648, que o maior valor permitido de uma varivel int, necessrio colocarmos a letra L (maiscula ou minscula) no final do nmero para indicarmos que um long. 10

Obs: Se alguma operao aritmtica cria um resultado que excede um dos limites estabelecidos para o tipo inteiro empregado, no h qualquer indicao de erro para avisar sobre essa ocorrncia. Ao invs disso, um complemento de dois do valor obtido ser o resultado. Por exemplo, se a varivel for do tipo byte, ocorrem os seguintes resultados: 127+1 = -128, 127+9=-120 e 127+127=-2. Entretanto, uma exceo do tipo ArithmeticException levantada caso ocorra uma diviso por zero. Vejamos o seguinte cdigo:
public class Arith { public static void main(String args[]) { byte a = 127; short b = 32767; int c = 2147483647; long d = 9223372036854775807L; int e = 0; a += 1; b += 1; c += 1; d += 1; System.out.println("Valor de a = " + System.out.println("Valor de b = " + System.out.println("Valor de c = " + System.out.println("Valor de d = " + d /= e; // Vai dar erro porque e = } }

a); b); c); d); 0

com seu respectivo resultado de execuo:


C:\jdk1.4.1.\Aula>java Arith Valor de a = -128 Valor de b = -32768 Valor de c = -2147483648 Valor de d = -9223372036854775808 Exception in thread main java.lang.ArithmeticException: / by zero at Arith.main(Arith.java:18)

Porm, se substituirmos as atribuies por:


a b c d = = = = a b c d + + + + 1; 1; 1; 1;

iremos obter um erro de compilao indicando incompatibilidade de tipos e solicitando uma converso (casting ou coero) explcita de tipos. Isso se deve ao fato de que, a maioria das operaes aritmticas envolvendo inteiros produz um int, independentemente do tipo original dos operandos. Como um int possui 32 bits, um short 16 e um byte 8, tal operao no possvel. Ento as duas primeiras atribuies iro resultar em erro, a terceira se trata de uma varivel int e a quarta se trata de uma varivel long (64 bits). Nesses casos, necessrio utilizar o operador de coero ou type cast, da seguinte forma:
a = (byte)(a + 1); b = (short)(b + 1);

11

A tabela a seguir mostra as promoes permitidas para os tipos de dados primitivos:


Tipo double float long int char short byte boolean Promoes permitidas nenhuma double float ou double long, float ou double int, long, float ou double int, long, float ou double short, int, long, float ou double nenhuma (no so considerados nmeros em Java)

Exerccios:
1) Criar uma aplicao para calcular o salrio de um trabalhador a partir do nmero de horas trabalhadas e o valor da hora. Estes valores devem ser armazenados em variveis inteiras. Mostre o salrio. 2) Criar uma aplicao que insira um valor em uma varivel int. Calcular e mostrar o menor nmero possvel de notas de 100, 50, 20, 10, 5, 2 e 1 em que o valor pode ser decomposto. Ex.: 389 pode ser decomposto em 3 notas de 100, 1 de 50, 1 de 20, 1 de 10, 1 de 5, 2 de 2 e 0 de 1. Dica: Utilizar o resto da diviso de inteiros (%) 3) Criar uma aplicao que declare e inicialize dois valores short representando, respectivamente, um valor de hora e um de minutos e informe quantos minutos se passaram desde o incio do dia. Exemplo:
valores atribudos : 13 15 mostra : 795 minutos

Tipos de Ponto Flutuante


Em Java, existem duas categorias de variveis de ponto flutuante: float armazena valores numricos em ponto flutuante de preciso simples e double de preciso dupla. Ambas seguem norma: IEEE Standard for Binary Floating Point Arithmetic, ANSI/IEEE Std. 754-1985 (IEEE, New York). O fato de obedecer a essa norma que torna os tipos de dados aceitos pela linguagem Java to portveis. Esses dados sero aceitos por qualquer plataforma, independendo do tipo de sistema operacional e do fabricante do computador. A representao dos valores em ponto flutuante pode ser feita usando a notao decimal (exemplo: -24.321) ou a notao cientfica (exemplo: 2.52E-31). Alm dos possveis valores numricos que uma varivel de ponto flutuante pode assumir h tambm os seguintes: menos infinito mais infinito zero NAN - not a number

12

Estes so requeridos pela norma. O mais infinito usado, por exemplo, ao somarmos 1 ao maior valor possivelmente representvel por esse sistema.

Operaes com tipos de ponto flutuante


Muitas das operaes realizveis com inteiros (porm no todas) tm anlogas para nmeros de ponto flutuante. Eis um resumo: Operao
=

Descrio Operador de atribuio ==, != Operadores de igualdade e diferena <, <=, >, >= Operadores de desigualdade +, Sinais unrios +, -, *, / Adio, subtrao, multiplicao e diviso +=, -=, *=, /= Operadores de atribuio com adio, subtrao, multiplicao e diviso ++, -Operadores unrios de incremento e decremento Um valor como 3.14159265 considerado double como padro, se voc quer atribuir esta constante a um float, faa o type cast explicitamente:
float a; a=(float)3.14159265; //a recebe PI

Ou ento usar uma terminao em f para indicar que o nmero deve ser representado como float:
float a=3.14159265f //ou F maiusculo

Exerccios:
1) Criar uma aplicao para calcular e mostrar as mdias aritmtica e harmnica de trs valores. Os trs valores devem ser double e as duas variveis para as mdias devem ser float.
ma = (a + b + c ) / 3; mh = 3 / (1/a + 1/b + 1/c );

2) Criar uma aplicao que declare trs variveis a1 (double), an (double) e r (double), respectivamente o 1o termo de uma progresso aritmtica, o ltimo termo da progresso e a razo desta progresso. Atribua valores a essas variveis. Aps, determinar a soma dos termos desta progresso aritmtica e mostrar. Obs: n e Sn devem ser float.
n = an a1 + r r Sn = (a1 + an) . n 2

13

Vetores e Matrizes
Semelhante s linguagens C, C++ e Pascal, a linguagem Java tambm d suporte a vetores e matrizes (arrays) de diversas formas. Os vetores constituem uma forma muito conveniente de organizar informaes em fileira. Por exemplo, podemos formar um vetor com as notas de cinco alunos de uma sala de aula do seguinte modo:
float nota[] = { 7.8f, 8.4f, 4.2f, 1.8f, 6.4f };

Neste caso nota[0] a nota do primeiro aluno, isto , 7.8, nota[1] a nota do segundo, ou seja, 8.4, e assim por diante. A utilizao de vetores e matrizes em Java envolve trs etapas: 1. Declarar o vetor ou matriz. Para isto, basta acrescentar um par de colchetes antes ou depois do nome da varivel. Por exemplo:
int ind[]; double A[][],T[][]; float []nota;

2. Reservar espao de memria e definir o tamanho. preciso definir o tamanho do vetor, isto , a quantidade total de elementos que ter de armazenar. Em seguida necessrio reservar espao de memria para armazenar os elementos. Isto feito de maneira simples pelo operador new:
ind = new int[10]; nota = new float[70]; A = new double[10][20];

Obs.: possvel juntar as duas primeiras etapas, realizando a declarao e a reserva de memria, assim: int ind[]= new int[10]; 3. Armazenar elementos no vetor ou matriz. Para armazenar uma informao em um dos elementos de um vetor ou matriz, necessrio fornecer um ndice que indique a posio desse elemento. Por exemplo, para armazenar um valor na quarta posio do vetor nota, fazemos o seguinte:
nota[3] = 5.2f;

Como podemos observar, os ndices comeam em zero e vo at o nmero de posies reservadas, menos um. No vetor nota criado acima, os ndices vlidos vo de 0 at 69. Caso haja a tentativa de atribuir um valor a um elemento cujo ndice esteja fora desse intervalo, ocorrer um erro que impedir a execuo do programa. Por isso, necessrio um certo cuidado ao manejar com esses ndices, garantindo o perfeito funcionamento do programa. Existe, porm, um atalho para esses trs passos quando desejamos criar um vetor com valores atribudos de modo esttico. Foi o que fizemos no primeiro exemplo acima, declarando o vetor 14

com as notas de cinco alunos. Nesse caso, espao suficiente para as notas de cinco alunos foi reservado e as notas foram guardadas em respectivas posies do vetor.
nota

Entretanto, nem sempre to fcil assim. Em geral, estaremos interessados em trabalhar com vetores muito maiores, e cujos elementos sejam provenientes de outras fontes, que variam com o tempo. Assim, seremos obrigados a seguir os passos acima. Eis mais alguns exemplos de vetores e matrizes:
// 11 primeiros termos da seqncia de Fibonacci: long Fibonacci[] = {1,1,2,3,5,8,13,34,55,89,144}; // Tabela de sen(n*pi/6), n=0,1,2,...5 float seno[] = {0.0000f,0.5000f,0.8660f,1.0000f,0.8660f,0.5000f}; // Tabela de log(1+n), n=0,2...99: double tlog[] = new double[100]; for(int n=0; n<100; n++) tlog[n] = Math.log(1+n); // Matriz dos coeficientes double A[][] = { {1,2,3}, {0,1,3}, {0,0,-1} };

Exerccios (no utilizar laos de repetio):


1) Criar uma aplicao que insira valores inteiros em um vetor de 6 posies na sua declarao. Declare um outro vetor qualquer para armazenar 6 valores float. Declare tambm uma varivel double qualquer e insira um valor nela. Aps, troque o primeiro valor do vetor de inteiros com o ltimo, o segundo com o penltimo e o terceiro com o antepenltimo. Por fim, preencha o vetor float com os elementos do vetor de inteiros na ordem inversa multiplicados pelo valor da varivel double. Mostre, ao final, os elementos de cada um dos vetores. 2) Criar uma aplicao que crie um vetor de 10 posies do tipo char e preencha-o com 10 caracteres na sua declarao. Crie tambm um vetor de 10 posies do tipo byte. Aps, preencha o vetor do tipo byte com o valor decimal do caracter correspondente a mesma posio do vetor do tipo char. Mostre os elementos dos dois vetores. 3) Criar uma aplicao que crie um vetor de 7 posies do tipo short e preencha com valores quaisquer. Aps, crie uma matriz do tipo long 2x7 que contenha, na primeira linha, o quadrado de cada um dos sete elementos do vetor e, na segunda linha, o cubo de cada um dos sete elementos do vetor. Mostra a matriz ao final.

Exerccios de reforo:
1) Sejam vA e vB dois vetores contendo 6 elementos cada, o primeiro long e o segundo double. Criar uma aplicao para: a) Atribuir valores quaisquer para vA e vB. b) Calcular e mostrar a soma dos elementos de vA. c) Calcular e mostrar a soma dos elementos de vB. 15

d) Criar o vetor vC (float), que a soma dos vetores vA e vB. Mostre-o. e) Obter o vetor vD (float), subtraindo vB de vA. Mostre-o. f) Calcular e mostrar o produto escalar de vA por vB, isto , vA[0]*vB[0] + vA[1]*vB[1] + .......+ vA[5]*vB[5]. 2) Criar uma aplicao para intercalar dois vetores de 8 elementos cada vet1 (int) e vet2 (long), formando o vetor vet3 (short). Mostre o vet3. Aps, crie uma matriz quadrada mat que caiba todos os elementos do vet3, inserindo cada elemento na matriz, de forma seqencial. Depois, troque toda primeira linha com a ltima. Por fim, efetue os seguintes clculos e mostre: a) b) c) d) e) A soma da linha 2 da matriz. A soma da coluna 0 da matriz. A soma da Diagonal Principal. A soma da Diagonal Secundria. A mdia aritmtica da coluna 1.

3) Criar uma aplicao que declare uma matriz String de duas linhas, e armazene o nome de cada uma das cinco cobaias utilizadas em cada uma das duas experincias, sendo que a primeira linha so as cobaias macho e a segunda so as cobaias fmeas. Aps, crie uma matriz float de quatro linhas que armazene os seguintes dados em cada linha: linha 1: a massa corporal das cobaias macho antes das experincias linha 2: a massa corporal das cobaias macho depois das experincias linha 3: a massa corporal das cobaias fmeas das experincias linha 4: a massa corporal das cobaias fmeas depois das experincias Tendo essas informaes, mostre a informao de cada cobaia, assim: A cobaia macho Juca
possui a massa corporal 88.55 antes da experincia e ganhou 2.11, passando a 90.66. Por fim, faa a mdia de massas corporais dos machos e das fmeas, antes e depois

das experincias, mostrando os valores.

Programao Orientada a Objetos


O Modelo de Objetos um paradigma de desenvolvimento de software baseada na construo de elementos computacionais que mimetizam objetos do mundo real. Java uma linguagem de programao orientada a objetos. Para compreender melhor isso necessrio ter em mente os conceitos de POO (Programao Orientada a Objetos) ou OOP (Object-Oriented Programming). Atualmente existem muitas linguagens POO. Simula foi a primeira linguagem a introduzir o conceito de classe em 1967, mas SmallTalk foi a primeira a implementar todos os aspectos 16

importantes da POO em 1980. Em seguida surgiram as linguagens hbridas, tais como C++, Objective-C, Ada, Eiffel, Sather, CLOS e Object Pascal. A base da POO reside na ideia da abstrao, ou seja, tentar traduzir a realidade para processos em um computador. O elemento chave da POO o conceito de classe, mas existem outros conceitos importantes.

Classes
Uma classe refere-se genericamente a uma entidade que rene uma estrutura interna, um estado e mtodos de comportamento. Em uma linguagem orientada a objetos, uma classe est relacionada a um tipo de dado. Uma classe a descrio abstrata de um grupo de objetos, cada um com um estado especfico, mas todos capazes de desempenhar as mesmas operaes. Todo objeto uma instncia de uma classe (o ato de criar um objeto se chama instanciao). Os objetos so entidades reais, pois na execuo da aplicao, eles ocupam parte da memria para sua representao interna. Por exemplo, uma garrafa um objeto que tem um estado (pode estar cheia ou vazia e pode possuir diferentes contedos) e que possui algumas operaes, como encher, esvaziar, abrir, fechar, trocar seu contedo. Naturalmente algumas das operaes dependem do estado. Assim, pode-se afirmar que uma classe uma definio de tipo que tem alguns campos ou atributos (que definem seu estado) e alguns mtodos, cujo comportamento depende do estado do objeto. Por exemplo, se tivssemos uma classe Semaforo contendo um nico campo chamado vermelhoVerdeAmarelo, ento o estado de Semaforo determinado pelo valor desse campo.
public class Semaforo { int vermelhoVerdeAmarelo = 0; // 0=vermelho,1=verde,2=amarelo public void alternar() { vermelhoVerdeAmarelo = ++vermelhoVerdeAmarelo % 3; } }

Os mtodos de uma classe, por sua vez, determinam a utilidade que uma classe ter. No caso da classe Semaforo, seu nico mtodo alternar() tem como funo provocar a mudana da luz de vermelho a verde, de verde a amarelo e de amarelo a vermelho, respectivamente, em cada nova chamada. Assim, se o mtodo alternar() for chamado em intervalos de tempo regulares, poderemos utilizar o estado da classe Semaforo para controlar um semforo com luzes reais. Em um diagrama de classes da UML (Unified Modeling Language), que a linguagem padro para modelar classes da Orientao a Objetos, representaramos essa classe da seguinte forma:

17

Mtodos
Os mtodos definem as aes a serem tomadas a partir dos campos declarados nas classes. Os mtodos correspondem aos conceitos comuns de funes e procedimentos. Na teoria das Linguagens de Programao, funes so iguais aos procedimentos, exceto pelo fato de que elas podem retornar um valor. Existem linguagens de programao que diferem funes de procedimentos na sua assinatura. Exemplos: Pascal: Procedure - Function, VB: Sub Function. Em Java, como em C, no existe uma palavra reservada especfica para identificar isso, ento, se no houver retorno, ou seja, se o retorno for void, o mtodo pode ser considerado um procedimento. Exemplos:
void meuProcedimento() int minhaFuncao()

De qualquer forma, em POO, as funes e procedimentos so chamados de mtodos. A sintaxe completa para a declarao de um mtodo a seguinte:
[moderadores de acesso] [modificador] [tipo do valor de retorno] [nome] ([parmetros ou argumentos]) throws [lista de excees] { [corpo] }

onde os termos em itlico so opcionais (ou acessrios). Vamos analisar na sequncia dessa apostila cada um dos termos: [moderadores de acesso], [modificador], [tipo do valor de retorno], [argumentos] e [lista de excees]. A declarao mais simples que podemos fazer de um mtodo (lembrando que isso deve ser feito dentro de uma classe) a seguinte:
void [nome do mtodo] () { [corpo do mtodo] }

onde [nome do mtodo] um identificador que define o nome pelo qual o mtodo conhecido, e [corpo do mtodo] consiste no cdigo-fonte em si do mtodo. Por exemplo:
public class Numero { double x = 1; void print() { System.out.println("O valor e " + x); }

Esse mtodo print() poderia receber um valor externo (conhecido como parmetro ou argumento), assim:
public class Numero { void print(double x) {

18

} }

System.out.println("O valor e " + x);

Um mtodo pode retornar um valor apenas, e necessrio declarar o tipo de dado desse retorno. Um exemplo de mtodos que retornam valores:
public class Calculadora { int soma(int a, int b) { return a + b; } double produto(double a, double b) { return a * b; } }

Exemplo de utilizao da classe Calculadora e dos mtodos soma e produto:


public public class CalcExec { public static void main(String args[]) { Calculadora calc = new Calculadora(); int r,a,b; a = 2; b = 3; r = calc.soma(a,b); System.out.println("A soma de 2 e 3 e " + r); System.out.println("O Produto de 2 e 3 e " + calc.produto(2,3));

} }

Hierarquia e Herana
Outro conceito muito utilizado em POO a herana (derivao de classes). Com a herana, possvel criar uma nova classe, definindo-a em termos de outra classe existente. Se isso ocorrer, a nova classe, chamada subclasse, herda todos os campos, mtodos e propriedades da superclasse. Se eu tivesse uma classe garrafa, por exemplo, possvel herdar, a partir de uma garrafa genrica, garrafas de plstico, de vidro ou especficas, como de cerveja ou vinho. Cada garrafa vai ter todos os atributos e operaes realizadas sobre a garrafa genrica, alm de atributos e operaes prprios, como modo de abrir, por exemplo. Nesse processo, os dados (campos) e mtodos de uma classe existente, chamada classe pai, ou superclasse, so herdados pela nova classe, chamada subclasse, ou classe filha, ou ainda classe derivada. E o conjunto de classes ligadas entre si pelo relacionamento de herana forma o que chamamos de hierarquia de herana. Suponhamos, por exemplo, que tenhamos declarado previamente a seguinte classe:
public class Poligono { int cx, cy; // Coordenadas do centro do polgono

19

Esta classe define em linhas gerais o que um polgono, guardando uma nica caracterstica comum a qualquer polgono, isto , as coordenadas de seu centro. Agora, suponhamos que desejamos criar uma classe para guardar informaes sobre um quadrado, alm de ter um mtodo para calcular a sua rea:
public class Quadrado extends Poligono { int lado; // Comprimento de um lado do quadrado public void calculaArea() { double area; area = lado * lado; System.out.println("A rea do quadrado " + area); } }

A classe quadrado declarada desse modo se diz uma classe filha da classe Poligono, da qual herda os dados (e os mtodos) nela contidos. Claro que, se temos uma classe pai, porque normalmente precisamos ter mais do que uma classe filha. Desejando fazer uma classe para representar um retngulo, bastaria fazer:
public class Retangulo extends Poligono { int base, alt; // Base e altura do retngulo public void calculaArea() { double area; area = base * alt; System.out.println("A rea do retngulo " + area); } }

Em UML, representamos a herana da seguinte forma:

20

Nota 1: Toda classe que no possuir um extends, automaticamente, e implicitamente, possuir uma derivao da classe Object, ou seja, ir herdar campos e mtodos dessa classe. como se tivssemos a seguinte declarao de classe para Poligono:
public class Poligono extends Object {...}

Nota 2: Esse tipo de classe, que possui dados puros, e mtodos que agem sobre esses dados, considerada classe de negcio. As classes de negcio so aquelas que ditam as regras de uma situao especfica que se deseja abstrair do mundo real para o computador. A partir delas, so criados os conhecidos objetos de negcio (BO-Business Objects). Nota 3: No existe herana mltipla em Java. Em contraste com a linguagem C++, em Java somente possvel derivar uma classe a partir de uma outra, e no de vrias.

Objetos
Uma particular instncia de uma classe chamada objeto. Podemos dizer que as classes no ocupam espao na memria, por serem abstraes, enquanto que os objetos ocupam espao de memria por serem concretizaes dessas abstraes. Nas declaraes acima, introduzimos algumas classes que permitem representar polgonos. Porm, no instanciamos nenhuma das classes criando particulares objetos a partir dessas classes. Por exemplo, a partir da classe Quadrado, podemos fazer objetos representando quadrados de diversos comprimentos laterais, ou retngulos de diferentes dimenses. Para que possamos trabalhar com objetos dessas classes, devemos ter algum tipo de classe no estilo aplicao, seja ela visual ou no. Exemplos podem ser Frames (janelas), Applets (miniaplicativos que rodam em navegadores), Midlets (aplicaes para aparelhos mveis), ou at mesmo Aplicaes Console, que so classes com execuo em modo textual, como o exemplo que segue.
public class appTestaPoligonos { public static void main(String args[]) { Quadrado q1, q2, q3; q1 = new Quadrado(); q2 = new Quadrado(); q3 = new Quadrado(); // declarao de quatro instncias ou objetos // instanciao

Retangulo r1 = new Retangulo(); // declarao e instanciao q1.lado = 1; q2.lado = 2; q3.lado = 7; r1.base = 3; r1.alt = 4; r1.cx = 0; r1.cy = 0; // // // // // O quadrado q1 ter os lados de comprimento 1 O quadrado q2 ter os lados de comprimento 2 O quadrado q3 ter os lados de comprimento 7 O retangulo r1 ter base 3 e ... altura 4, e centrado na origem

} }

21

Exemplo a ser feito com o Professor:


1) Criar classes com hierarquia de herana baseadas em informaes de veculos: Classe pai Veiculo e filhas VeiculoTerrestre, VeiculoMaritimo, VeiculoAereo. Definir alguns campos ou atributos e alguns mtodos para essas classes.

Exerccio:
1) Criar uma classe Garrafa, que possui um campo int volume. Criar uma classe GarrafaVinho como subclasse da classe Garrafa. Criar uma outra classe GarrafaCerveja tambm como subclasse da classe Garrafa. As duas subclasses no possuem nenhum campo, apenas um mtodo abrir() cada que, para GarrafaVinho mostra na tela saca-rolha e para GarrafaCerveja mostra na tela abridor. Aps, criar uma classe pblica AppTestaGarrafa que possui um mtodo main(), onde devem ser instanciados dois objetos: objGV do tipo GarrafaVinho e objGC do tipo GarrafaCerveja. O volume de objGV 200 e de objGC 300. Inserir esses dados para os objetos (instncias). Aps, mostrar na tela os volumes dos dois objetos e chamar o mtodo abrir() dos dois objetos para ver o resultado.

Pacotes (packages)
Usamos pacotes para organizar as classes que possuem algo em comum. Pacotes, a grosso modo, so apenas pastas ou diretrios do sistema operacional onde ficam armazenados os arquivos fonte de Java. As IDEs fornecem maneiras de criar pacotes dentro das pastas dos projetos. A partir do momento que inserimos uma classe em um pacote, a primeira linha do arquivo que contem a classe Java vai possuir a identificao desse pacote, assim:
package meupacote;

Java possui vrios pacotes com outros pacotes internos e vrias classes j prontas para serem utilizadas. Alm disso, teremos os nossos prprios pacotes, como forma de nos organizarmos. Dentre os pacotes Java podemos dar como exemplo o pacote AWT (Abstract Windowing Toolkit), que possui as classes necessrias para se criar um ambiente grfico API (Janelas). Para utilizar as milhares de classes contidas nos inmeros pacotes de Java devemos ou nos referenciar diretamente classe ou import-la. Para importar classes de um pacote usamos a instruo import. Para separar um pacote de seu sub-pacote usamos um ponto. Se quisermos importar todas classes de um pacote podemos utilizar um coringa, o asterisco (*). Na verdade, o compilador, no momento da criao do bytecode, ir apenas incluir as classes que realmente so utilizadas. Ex.:
import java.awt.*; import meupacote.minhaClasse;

Exerccio:
22

1) Criar um pacote pkggarrafa e arrastar as classes Garrafa, GarrafaVinho e GarrafaCerveja para ele. Verificar a insero do package na primeira linha em cada classe. Colocar a classe AppTestaGarrafa em um outro pacote de nome pkgprincipal. Verificar e corrigir os erros ocasionados por essas aes, como a necessidade de importao do pacote e a possvel necessidade de ter que alterar o moderador de acesso dos campos da classe (o assunto abordado logo a seguir).

Visibilidade e Encapsulamento
Os campos, mtodos e propriedades da classe podem possuir uma visibilidade especificada, ou seja, possvel definir os seus escopos dentro da rea onde os objetos da classe possuem atuao. Isso permite ao programador utilizar um conceito de OO conhecido como encapsulamento. Encapsular um campo, mtodo ou propriedade dentro de uma classe significa ocultar essa informao para os objetos que iro referenci-la. Isto traz uma srie de vantagens. Uma vez concluda uma classe complicada, por exemplo, virtualmente possvel esquecermos suas complicaes internas, passando a trat-la atravs de seus mtodos. Criamos, assim, programas mais robustos e confiveis. Em uma abordagem OO, os campos de uma classe normalmente so encapsulados, para no permitir que valores invlidos sejam inseridos neles. E para realizar o encapsulamento necessrio conhecer um pouco mais dos moderadores de acesso, que so responsveis pela visibilidade.

Moderadores de Acesso
Os moderadores de acesso so empregados para restringir o acesso a campos, mtodos e classes. Os moderadores de acesso existentes em Java so os seguintes:
public:

O mtodo, campo ou classe declarado com este moderador pblico e pode ser chamado a partir de mtodos contidos em qualquer outra classe. Esta a condio de menor restrio possvel. ou default: no so palavras reservadas da linguagem, so apenas nomes dados para o tipo de encapsulamento padro (default), que ocorre quando no existe um especificador. Estes mtodos, campos ou classes so acessveis somente nos mtodos das classes que pertencem ao package em que foram criados.
friendly protected:

O mtodo ou campo (classes no possuem esse moderador) protegido e pode ser chamado por todas as classes que compem um conjunto maior chamado package. A nica diferena existente entre o protected e o default que o protected permite que subclasses definidas em outros pacotes tenham visibilidade sobre os campos e mtodos declarados com esse modificador.
private: O mtodo ou campo (classes no possuem esse moderador) privativo da classe que o contm e seu uso vedado a qualquer outra classe. o moderador mais utilizado para se fazer o encapsulamento.

Exemplo: 23

// classe Numero class Numero { private double x = 1; double y = 2; public void print1() { System.out.println("O valor e "+x); } private void print2() { System.out.println("O valor e "+x); } } // classe principal public class PrintNum { public static void main(String args[]) { numero num = new numero(); num.print1(); // correto num.print2(); // ilegal num.x = 10; // ilegal num.y = 20; // correto } }

Os diferentes nveis de controle de acesso


Visibilidade

A partir da mesma classe A partir de qualquer classe no mesmo pacote A partir de qualquer classe fora do pacote A partir de uma subclasse no mesmo pacote A partir de uma subclasse fora do mesmo pacote

public sim sim sim sim sim

protected sim sim no sim sim

default sim sim no sim no

private sim no no no no

Encapsulmento, Setters e Getters


Como comentado, o objetivo de se encapsular campos torn-los protegidos para o acesso atravs dos objetos. Se no houver isso, os campos de uma classe Data, por exemplo, seriam visveis pelos objetos criados. Assim, se poderia inserir um valor invlido em mes, por exemplo:
objCalendario.mes = 13

Se os campos forem encapsulados, os campos no se tornam visveis para o acesso atravs do objeto. A maneira de se encapsular o campo na classe atravs da utilizao do moderador private, assim:
private int mes;

Claro que, por conta disso, necessrio ter uma maneira para inserir e recuperar valores dos campos a partir do objeto. E isso se faz a partir da criao de mtodos setters e getters. No exemplo do campo mes, seriam criados os seguintes mtodos na classe Data.
//mtodo set public void setMes(int m) {

24

mes = m;

//mtodo get public int getMes() { return mes; }

O mtodo setMes recebe um valor externo e atualiza o campo da classe. Dessa forma, apesar do exemplo no estar fazendo o tratamento do erro (ser visto posteriormente na seo Lanamento de Excees), possvel de ser feito. Na aplicao, o objeto atribuiria um valor a mes assim:
objCalendario.setMes(10);

J o mtodo getMes retorna o valor do campo mes. Assim, possvel utiliz-lo na aplicao, a partir do objeto. Exemplo:
System.out.println("O ms " + objCalendario.getMes());

this e super
O this e o super so duas palavras reservadas que representam, respectivamente o acesso classe atual (this) e o acesso superclasse, ou classe pai (super). Existem situaes especficas onde necessria a utilizao dessas palavras reservadas. A exemplificao dessas situaes ir ocorrer na sequncia da apostila. Uma primeira situao de utilizao do this acontece em uma conveno Java na criao dos mtodos setters. comum utilizar o mesmo nome para o parmetro recebido e o campo da classe. Assim, no haveria forma do mtodo saber o que varivel local e o que campo da classe. Nesses casos podemos utilizar a especificao this, assim:
public void setMes(int mes) { this.mes = mes; }

Assim, this.mes refere-se ao campo mes declarado na classe, enquanto mes refere-se ao parmetro recebido externamente pelo mtodo. Em um outro exemplo, teramos a classe Inquilino dessa forma:
public class Inquilino { private String nomeInquilino; private int apto; priate boolean idoso; //mtodo set public void setnomeInquilino(String nomeInquilino) { this.nomeInquilino = nomeInquilino; } //mtodo get public String getnomeInquilino() {

25

return nomeInquilino;

//mtodo set public void setApto(int apto) { this.apto = apto; } //mtodo get public int getApto() { return apto; } //mtodo set public void setIdoso(boolean idoso) { this.idoso = idoso; } //mtodo get(is) public boolean isIdoso() { return idoso; } }

Percebe-se que o mtodo isIdoso() no inicia por get. uma conveno utilizar is para campos do tipo boolean, exatamente por ficar com leitura mais adequada, j que isIdoso significa " Idoso".

Exerccio:
1) Nas classes criadas para Veculos, encapsular os campos e criar os setters e getters.

Mtodo toString() e Substituio (override) de mtodo


O mtodo toString() um mtodo existente na classe Object e, como visto anteriormente, ela a classe pai de todas as classes Java. Na figura a seguir temos a descrio desse mtodo (capturado do Eclipse).

26

Em uma traduo literal, o toString() deve retornar um String que "representa textualmente" o objeto da classe em questo. O resultado dever ser uma concisa, mas informativa, representao textual, que seja fcil para algum ler. recomendado que todas subclasses substituam (override) esse mtodo. Dessa forma, entra em cena um conceito muito importante da Orientao a Objetos, conhecido como substituio (ou sobrescrita) de mtodo (override). Para que isso acontea, precisamos substituir algum mtodo j existente na classe pai, lembrando que a assinatura deve permanecer a mesma, ou seja, o nome do mtodo, seu retorno, e a quantidade e tipos de dados dos parmetros devem ser iguais. Assim, o toString() da nossa classe Inquilino ficaria assim:
public String toString() { return "Nome do Inquilino = " + nomeInquilino + " Apartamento = " + apto; }

Dica: As IDEs (Eclipse e NetBeans) possuem ferramentas para gerao automtica, tanto dos setters e getters quanto do toString(). Nota 1: Se, em uma hierarquia de herana no houver nenhuma substituio do mtodo toString() da classe Object, ele estar disponvel para todas as classes da hierarquia no seguinte formato: getClass().getName() + '@' + Integer.toHexString(hashCode()). Nota 2: A substituio de mtodo sempre ocorre de classe pai para classe filha, pois no possvel criar dois mtodos de mesmo nome e assinatura na mesma classe.

Exerccio:
27

1) Nas classes criadas para Veculos, criar o toString() em cada classe.

Anotaes (Annotations)
Se for utilizado o NetBeans, por exemplo, para gerar o toString(), automaticamente ele adicionar uma linha iniciada por um @, o que chamamos de Anotao, assim:
@Override

Quando voc substitui um mtodo de uma classe (mais adiante trabalharemos com substituio dos nossos prprios mtodos), voc pode colocar a anotao @Override para indicar que esse mtodo est sendo substitudo. Assim, se houver a tentativa de alterar a assinatura desse mtodo na superclasse, o Java gerar um erro de compilao na subclasse indicando que um mtodo com aquela assinatura no existe na superclasse. possvel criar nossas prprias anotaes. As Anotaes so uma forma de estendermos caractersticas prprias, de acordo com a necessidade. Mas isso algo um pouco mais avanado, e que no ser aprofundado aqui.

Exerccio:
1) Criar uma classe Pessoa que possui dois campos encapsulados codigo (int) e nome (String), com seus respectivos setters e getters. Criar um mtodo toString(), substituindo o mtodo existente na classe Object, que deve mostrar os dados da pessoa na forma Codigo=xxx Nome=xxxxx. Incluir a anotao @Override. Criar uma classe PessoaFisica derivada de Pessoa, que possui um campo encapsulado cpf (String), o setter e o getter respectivo. Criar um mtodo toString(), substituindo o mtodo existente na classe Pessoa (incluir a anotao @Override) que deve retornar os dados da pessoa na forma Codigo=xxx Nome=xxxxx Cpf=xxxxx. IMPORTANTE: para buscar o cdigo e o nome da classe pai, utilize o mtodo toString()dessa classe. Para isso, ser necessrio utilizar a palavra reservada super. Criar uma classe PessoaJuridica, derivada de Pessoa, que possui um campo encapsulado cnpj (String). Realize as mesmas aes feitas para construo da classe PessoaFisica. Por fim, criar uma classe pblica AppTestaPessoas, que deve ter um mtodo main() para instanciar duas pessoas fsicas (PF1 e PF2) e duas pessoas jurdicas (PJ1 e PJ2). Alimentar os dados das instancias PF1 e PF2 (codigo, nome e cpf) com valores quaisquer e alimentar tambm os dados das instncias PJ1 e PJ2 (codigo, nome e cnpj) com valores quaisquer. Aps, mostrar os dados a partir do mtodo toString() para cada uma das quatro instncias e verificar o resultado.

Construtores e Sobreposio (overload) de mtodo


Um mtodo construtor um mtodo especial que invocado no momento da instanciao. Por exemplo, para a criao do objeto objData: 28

Data objData = new Data();

o new Data() a invocao do construtor da classe. Porm, como possvel chamar um mtodo que no existe na classe? Sempre que criamos uma classe, o Java automaticamente vincula um mtodo construtor padro interno com o mesmo nome da classe, mas sem inicializar nenhum campo. Por isso, importante criarmos o construtor das classes a fim de inicializar os campos com os valores que acharmos necessrios para a criao dos objetos. Isso impediria por exemplo, que tivssemos uma data invlida, pois o objData seria criado com valores zerados para dia, ms e ano. Construtores normalmente so pblicos, e eles no possuem retorno. Nesse caso, o construtor para a classe Data poderia ser definido assim:
public Data(){ this.dia = 1; this.mes = 1; this.ano = 1900; }

Dessa forma, qualquer objeto criado teria como data inicial 1/1/1900. E se quisssemos permitir a criao de objetos de Data a partir de valores fornecidos no momento da instanciao. Nesse caso, precisaramos criar um segundo construtor, que receberia os parmetros, e alimentaria os campos da classe, assim:
public Data(int dia, int mes, int ano){ this.dia = dia; this.mes = mes; this.ano = ano; }

Como deu para perceber, temos dois mtodos com o mesmo nome na mesma classe, porm, com assinaturas diferentes. Isso, em POO, se cham sobreposio de mtodo (overload). Na criao do objeto, deve-se passar os valores iniciais, assim:
Data objData = new Data(10,11,2000);

ou passar variveis lidas a partir do usurio:


Data objData = new Data(varDia,varMes,varAno);

Uma situao importante aqui vem de encontro quela situao do encapsulamento, onde os campos foram protegidos para no permitir a insero de valores invlidos. Foi comentado que a validao dos valores lanados para os campos deve ser feito nos setters (o que ser abordado mais adiante). Pois bem, como o construtor recebe valores externos, h o risco de valores errneos serem passados, o que indica que haver uma duplicidade de testes, um no setter e outro no construtor. Como alternativa, poderamos utilizar os setters no construtor, assim, manteramos os testes em um lugar apenas. Ficaria dessa forma:
public Data(int dia, int mes, int ano){ setDia(dia); setMes(mes);

29

setAno(ano);

Nota 1: possvel ter mais de dois mtodos sobrepostos, o que, alis, muito comum. Isso significa que poderamos ter um terceiro, um quarto construtor. Nota 2: muito comum realizarmos overload de mtodos nomais, o que ser abordado em seguida. Nota 3: Em construtores de classes filhas, comum querermos inicializar os campos da classe pai. Para isso, recebemos os parmetros no contrutor da classe filha e passamos para a classe pai a partir da invocao do seu construtor. Isso se faz a partir do super().

Exerccio:
1) Incluir dois construtores em cada uma das classes: Pessoa, PessoaFisica e PessoaJuridica, um sem e outro com parmetros, sendo que, para as classes filhas deve se utilizar o que foi descrito na Nota 3. Testar na aplicao.

Exerccios de Fixao:
1) Baseado nas classes vistas em aula, imaginar algo possvel de ser abstrado e passar para classes em Java. obrigatrio ter: Herana com pelo menos duas classes filhas. Campos (ou atributos) encapsulados tanto na classe pai quanto nas filhas. Construtores (com overload). Mtodos tanto na classe pai quanto nas filhas, que tenham retorno de valores, como, por exemplo, o clculo de combustvel de um veculo baseado nos campos existentes. toString() em todas as classes (override). Uma classe estilo aplicao de teste para criar objetos (instanciar) e realizar testes com os campos e mtodos.

2) A partir do diagrama de classes bsico abaixo, cri-las no Java contendo os mesmos elementos do exerccio anterior.

Modificadores de Mtodos
30

Os modificadores de mtodos permitem especificar algumas propriedades de um mtodo. Abaixo a descrio de alguns deles:

o mtodo compartilhado por todos os objetos instanciados a partir da mesma classe. Tal mtodo denominado mtodo de classe. A mesma execuo se d a todas as instncias da classe. O mesmo acontece para variveis estticas. Elas so chamadas de variveis de classe. Em ambos os casos, a chamada se d pelo [classe].[varivel ou mtodo]. Um exemplo de variveis e mtodos de classe pode ser visto a seguir:
static: public class ContaInstancias { private static int numInstancias=0; public static int numInst() { return numInstancias; } public void addInstancia() { numInstancias++; }

public class AppTestaInstancias { public static void main(String args[]) { System.out.println("Inicio: "+ContaInstancias.numInst()+" inst."); ContaInstancias a = new ContaInstancias(); a.addInstancia(); ContaInstancias b = new ContaInstancias(); b.addInstancia(); ContaInstancias c = new ContaInstancias(); c.addInstancia(); System.out.println("Final: "+ContaInstancias.numInst()+" inst."); }

abstract:

Em uma hierarquia de classe, quanto mais alta a classe, mais abstrata a sua definio. Podemos declarar um mtodo sem contudo especificar seu corpo, dizendo-o abstrato. Isto funciona como uma espcie de lembrete para que alguma classe derivada complete a declarao fornecendo um corpo. Assim sendo, uma classe que contenha um mtodo abstrato, ou que seja derivada de alguma classe que contenha um mtodo abstrato, mas no complete sua declarao, no pode ser instanciada. Esse modificador ser abordado com mais exemplos no tpico "Polimorfismo". Exemplo:
abstract void calculaArea();

final:

Especifica que nenhuma classe derivada pode alterar ou redefinir este mtodo, ou seja, no pode haver substituio (override) desse mtodo. Um mtodo declarado como final deve ser obrigatoriamente seguido de um corpo.

Exerccio:
1) Esse exerccio dividido em vrias partes, a fim de identificar formas diferentes de se criar classes que no so exatamente classes de negcio, e sim classes utilitrias: 31

a. Criar uma classe Calculadora que tenha dois campos double v1 e v2. Criar quatro mtodos soma(), subtracao(), multiplicacao() e divisao() que devem fazer a operao correspondente nos campos v1 e v2 e mostrar. Criar uma classe pblica AppestaCalc que deve ter um mtodo main() para instanciar C1 de Calculadora. Inserir valores quaisquer para os campos v1 e v2 e chamar os quatro mtodos para verificar o resultado. b. Analisar as dificuldades de utilizao dessa classe. c. Alterar a classe Calculadora de forma que ela no tenha nenhum campo e os mtodos soma(), subtracao(), multiplicacao() e divisao() devem ter o recebimento de dois parmetros double e o retorno de um valor double, que o resultado da operao. Alm disso, os mtodos devem ser estticos. No AppTestaCalc faa as alteraes necessrias para testar. d. Utilizando o conceito de overload, criar um segundo mtodo divisao(), a fim de efetuar a diviso de inteiros. Teste na aplicao. 2) Criar uma classe Simbolos que no possui nenhum campo, mas possui um mtodo, o mtodo esttico getExtenso(), que deve receber um char como parmetro, e retornar um String que deve ser o nome desse parmetro por extenso. Os smbolos a serem testados so:
{ - Abre Chaves } - Fecha Chaves [ - Abre Colchetes ] - Fecha Colchetes ( - Abre Parenteses ) - Fecha Parenteses Se no for nenhum destes, retornar Nenhum

Aps, criar uma classe AppTestaSimbolos, que dever utilizar a classe Simbolos de maneira esttica, fazendo vrios testes com o mtodo criado. Exemplo: System.out.println(Simbolos.getExtenso('{')); Dica: utilizar o if, lembrando que o operador de igualdade em Java ==. 3) Criar uma classe que possua mtodos de classe estticos com alguma utilidade. Imagine algo que tenha o perfil para criar mtodos estticos. Depois, crie uma classe de teste para chamar os mtodos de forma esttica.

Exerccio de Reviso:
1) Criar uma classe Calendario com trs campos encapsulados dia, mes e ano, todos do tipo int. Criar os setters e getters e os construtores. Alm disso, os seguintes mtodos devem ser criados: deve retornar true se o ano for bissexto e false caso contrrio. Um ano bissexto de 4 em 4 anos. void incrementaDia() deve incrementar o campo dia em 1, considerando os finais de meses e os anos bissextos. 32
boolean isBissexto()

deve decrementar o campo dia em 1, considerando os finais de meses e os anos bissextos. String toString() deve retornar um String com os trs campos separados por uma / , ou seja dia+"/"+mes+"/"+ano.
void decrementaDia()

Aps, criar uma classe AppTestaCalend, que dever ter uma instncia Cal de Calendario. Inserir valores vlidos para os campos da instncia (dia, mes e ano). Aps, mostrar a data formatada na tela (toString), verificar se o ano bissexto (isBissexto) e testar o incremento (incrementaDia) e o decremento (decrementaDia) de dias, mostrando a data formatada em cada operao. 2) Em uma segunda etapa, alterar a classe Calendario, criando cinco novos mtodos:
A B C D E F G H I J = = = = = = = = = =

deve incrementar o campo mes em 1, considerando os finais de ano e a situao de que, ao mudar um ms, o dia pode ficar invlido. void decrementaMes() deve decrementar o campo mes em 1, considerando os finais de ano e a situao de que, ao mudar um ms, o dia pode ficar invlido. void incrementaAno() deve incrementar o campo ano em 1, a situao de que, ao mudar o ano estando no ltimo dia do ms 2 de um ano bissexto, o dia pode ficar invlido. void decrementaAno() deve decrementar o campo ano em 1, a situao de que, ao mudar o ano estando no ltimo dia do ms 2 de um ano bissexto, o dia pode ficar invlido. String getDiaDaSemana() deve retornar o dia da semana, baseado no algoritmo abaixo:
void incrementaMes() o inteiro de [(12 - Ms) 10] Ano - A Ms + (12 x A) o inteiro de (B 100) o inteiro de (D 4) 2 - D + E o inteiro de (365,25 x B) o inteiro de [30,6001 x (C + 1)] F + G + H + Dia + 5 o resto de (I 7), onde 0=SAB 1=DOM 2=SEG 3=TER 4=QUA 5=QUI 6=SEX

Aps, realizar os testes na classe AppTestaCalend.

Excees
Excees so eventos gerados automaticamente quando algo d errado em tempo de execuo. O objetivo do tratamento de excees fazer com que o problema seja reconhecido e tenha um tratamento adequado. Alguns exemplos de situaes onde podem ocorrer excees: entrada de dados invlida; falhas no tratamento de arquivos; falhas na comunicao entre processos; falhas de conexo a banco de dados; 33

falhas na utilizao de threads; erros aritmticos; erros de converso de tipos de dados; estouro de limites de arrays; e muitas outras...

As excees so "lanadas" (throw) a partir de mtodos ou operaes que so realizadas dentro do fluxo de nossa programao normal. Por exemplo, veremos que para converter um String qualquer para um tipo numrico, podemos utilizar os mtodos "parse" contidos nas classes destinadas aos tipos de dados bsicos, como Integer, Short, Double, Float, etc. Assim, o exemplo abaixo:
double x = Double.parseDouble(varString);

pode acarretar em um lanamento de exceo do tipo NumberFormatException caso o varString no tenha um valor adequado para converter para double. Nota: As classes de Exceo lanadas possuem a classe Exception como sua primeira classe na hierarquia de herana. No tpico "Lanamento de Excees" veremos como criar e lanar nossas prprias excees. Para evitar que erros ocorram, mensagens inadequadas apaream, ou atm mesmo aplicaes abortem, devemos tratar essas excees. O tratamento de excees no Java feito por meio de um mecanismo simples, que usa as seguintes palavras-chave:
try

incio de um bloco de cdigo protegido;

final de um bloco de cdigo protegido; introduz as instrues de tratamento de exceo.


catch

sempre ser executado depois do bloco try/catch. O importante saber que esse bloco sempre ser executado.
finally

Resumindo, a estrutura :
try { // aqui vai cdigo que pode lanar excees dos tipos // ExceptionType1 e ExceptionType2 } catch( ExceptionType1 opa1 ) { // aqui vai cdigo para tratar uma exceo do tipo // ExceptionType1 } catch( ExceptionType2 opa2 ) { // aqui vai cdigo para tratar uma exceo do tipo // ExceptionType2 } finally { // aqui vai cdigo que ser executado em qualquer caso }

No caso do exemplo anterior, poderamos proteger o cdigo da seguinte forma:


try{

34

double x = Double.parseDouble(varString); } catch (NumberFormatException erro){ System.out.println("Converso no permitida"); x = 0.0; }

Nota 1: Um try pode ter vrios catch, pois vrias excees podem ocorrer durante a execuo do bloco que est sendo protegido. Alm disso, se necessrio, pode-se colocar como ltimo catch o Exception, fazendo com que um "erro desconhecido" possa ser tratado tambm. Nota 2: Como visto, podemos ter vrios catch em um try. Podemos tambm ter ou no ter finally. possvel tambm ter try sem catch e com fnally. Vejamos um outro exemplo simples de exceo, capturando uma diviso por zero (ArithmeticException):
import java.io.*; public class Excecao { public static void main (String args[]) { int resultado=0, varint=5, varint2=0; System.out.println("Tentativa de dividir 5 por 0:"); try { resultado=varint/varint2; System.out.println("Resultado: "+resultado); } catch (ArithmeticException erro) { System.out.println("Ocorreu um erro tipo: "+erro.toString()); resultado=0; } System.out.println("Fim da Aplicao"); } }

Percebe-se que o resultado no foi mostrado, pois a exceo ocorreu na linha anterior mostragem. Se tentarmos alterar o valor da varivel varint2 para 2, por exemplo, veremos que a excecuo se dar normalmente, e o resultado ser mostrado.

Entrada/Sada de Dados
Todas as operaes de E/S no Java so fornecidas pelas classes contidas no pacote java.io, que deve ser importado. A leitura de dados a partir do console pode ser feita de vrias maneiras. Pode ser utilizada a classe Scanner, ou ainda a InputStream. Porm, uma das formas mais usuais a criao de um objeto da classe BufferedReader. Esta classe possui o mtodo readLine() que permite ler uma linha de texto e a devolve num String. Esse mtodo necessita, obrigatoriamente, do tratamento da exceo IOException. Para obter um BufferedReader associado entrada padro, devemos incluir a instruo:
BufferedReader entrada = new BufferedReader(new InputStreamReader(System.in));

35

Vejamos um exemplo:
import java.io.*; public class Leit{ public static void main(String args[]) { String nome = ""; BufferedReader ent = new BufferedReader(new InputStreamReader(System.in)); try { System.out.print("Digite seu Nome: "); nome = ent.readLine(); } catch (IOException e) { System.out.println("Erro de Leitura"); } System.out.println("OI " + nome); } }

Para a leitura de um nico caracter, uma maneira seria ler o String e utilizar apenas o primeiro caracter, assim:
char caracter = ent.readLine().charat(0);

Para leitura de dados numricos, devemos realizar as converses com os mtodos "parse", como visto na seo de "Excees", vista anteriormente. Basicamente, as classes e mtodos so:
Byte.parseByte() Short.parseShort() Integer.parseInt() Long.parseLong() Float.parseFloat() Double.parseDouble()

Exemplo:
try { System.out.print("Digite um valor inteiro: "); varshort = Short.parseShort(ent.readLine()); }catch (IOException e) { System.out.println("Erro de Leitura"); }

Como visto na seo "Excees", se um valor no numrico for digitado, uma exceo do tipo NumberFormatException pode ser lanada. Assim, devemos fazer o tratamento dessa exceo tambm, assim:
try { System.out.print("Digite um valor inteiro: "); varshort = Short.parseShort(ent.readLine()); }catch (IOException e) { System.out.println("Erro de Leitura"); } catch (NumberFormatException e) { System.out.println("A leitura deve ser numrica"); }

36

Exerccio:
1) Crie uma classe no estilo aplicao que mostre o cardpio abaixo dentro do mtodo main():
CARDAPIO 101-Cachorro quente......... 2,50 102-Hamburger............... 4,50 103-Pizza.................. 11,30 104-Refrigerante............ 1,50 105-Cerveja................. 5,00

Aps, solicitar o nome(String) do cliente, o item 1(short), a quantidade do item 1 (int), o item 2(short), a quantidade do item 2 (int). Com os valores digitados, solicitar um valor de desconto (double) e, s ento, calcular a conta, mostrando-a juntamente com o nome do cliente, assim: A conta do cliente fulano de tal xxx.xx.

Leituras com Testes de Validade


O problema nos exemplos de leitura vistos que o fluxo da aplicao continua aps mostrar a mensagem de erro. O ideal seria realizar a leitura novamente. Apesar do tpico "Laos de Iterao" ser visto posteriormente, precisaremos utilizar o do...while() aqui. Alm disso, utilizaremos o break, responsvel por "quebrar" um lao de repetio, encerrando-o. Vamos considerar quatro situaes de leituras que necessitam de testes de validade. Tipo 1: quando preciso testar uma varivel numrica (try..catch) SEM intervalo de valores.
do{ try{ System.out.print("Digite numero do funcionario: "); numFunc = Long.parseLong(entrada.readLine()); break; // quebra o lao quando conseguir passar sem erros }catch(IOException e){ System.out.print("Erro de leitura"); }catch(NumberFormatException e){ System.out.println("Leitura deve ser numrica"); } }while(true); // lao infinito

Tipo 2: quando eu preciso testar uma varivel numrica (try..catch) COM intervalo de valores
do{ try{ System.out.print("Digite numero do funcionario: "); numFunc = Long.parseLong(entrada.readLine()); if (numFunc <= 0) System.out.println("Valor deve ser positivo"); else break; // quebra o lao quando conseguir passar sem erros }catch(IOException e){ System.out.println("Erro de leitura"); }catch(NumberFormatException e){ System.out.println("Leitura deve ser numrica");

37

} }while(true);

// lao infinito

Tipo 3: quando a varivel no numrica (String) e necessrio testar intevalo de valores


do{ try { System.out.print("Digite nome do funcionario: "); nomeFunc = entrada.readLine().trim(); // o trim retira espaos(incio-fim) if (nomeFunc.equals("")) System.out.println("Nome deve ser preenchido"); } catch (IOException e) { System.out.println("Erro de leitura"); } }while(nomeFunc.equals(""));

Tipo 4: quando a varivel no numrica, char, e necessrio testar intevalo de valores


do{ try { System.out.print("Deseja realizar mais alguma operacao (s/n)? "); // o toLowerCase converte o caracter lido para minusculo continua = Character.toLowerCase(entrada.readLine().charAt(0)); if (continua != 's' && continua != 'n') System.out.println("Digite s ou n"); } catch (IOException e) { System.out.println("Erro de leitura"); } }while(continua != 's' && continua != 'n');

Exerccio:
1) A empresa ABC Ltda. decidiu conceder um aumento de salrios a seus funcionrios de acordo com a tabela abaixo: Salrio Atual 0 a 400.00 400.01 a 700.00 700.01 a 1000.00 1000.01 a 1800.00 1800.01 a 2500.00 Acima de 2500.00 ndice de Aumento 15% 12% 10% 8% 5% 2%

Criar uma aplicao que faa a leitura do nmero de um funcionrio (long e maior que zero), seu nome (String e no vazio) e seu salrio atual (float e maior que zero), e calcula o valor do salrio corrigido, mostrando juntamente com o ndice de aumento, assim: O

funcionrio 999 - fulano de tal teve um aumento de 99% e seu salrio corrigido 9999.99.

Repetio do Fluxo de uma Aplicao

38

desejvel, para muitas aplicaes, que o fluxo delas seja repetido, no estilo "Deseja Continuar?" A seguir dois exemplos dessa situao: Exemplo 1: Quando a sada do lao se d a partir de um nmero ou caracter qualquer:
public class ExDesejaContinuar1{ public static void main(String[] args) { int a, b, c; BufferedReader ent = new BufferedReader(new InputStreamReader(System.in)); do { // lao geral do{ // lao para testar o valor 1 try{ System.out.print("Digite valor 1 (-1 encerra): "); a = Short.parseShort(ent.readLine()); if (a < 0 && a != -1) System.out.println("Valor deve ser positivo"); else break;// quebra o lao quando o valor for correto }catch(IOException e){ System.out.println("Erro de leitura"); }catch(NumberFormatException e){ System.out.println("Leitura deve ser numrica"); } }while(true); // lao infinito if (a == -1) // teste para quebrar o lao break; // System.exit(0); do{ // lao para testar o valor 2 try{ System.out.print("Digite valor 2: "); b = Short.parseShort(ent.readLine()); if (b < 0) System.out.println("Valor deve ser positivo"); else break; // quebra o lao quando o valor for correto }catch(IOException e){ System.out.println("Erro de leitura"); }catch(NumberFormatException e){ System.out.println("Leitura deve ser numrica"); } }while(true); // lao infinito c = a + b; System.out.println("Resultado = " + c); } while (true);

} }

Exemplo 2: Quando a sada do lao se d a partir de uma pergunta:


public class ExDesejaContinuar2{ public static void main(String[] args) { int a, b, c; char continua = ' '; BufferedReader ent = new BufferedReader(new InputStreamReader(System.in)); do { // lao geral

39

do{ // lao para testar o valor 1 try{ System.out.print("Digite valor 1: "); a = Short.parseShort(ent.readLine()); if (a < 0) System.out.println("Valor deve ser positivo"); else break;// quebra o lao quando o valor for correto }catch(IOException e){ System.out.println("Erro de leitura"); }catch(NumberFormatException e){ System.out.println("Leitura deve ser numrica"); } }while(true); // lao infinito do{ // lao para testar o valor 2 try{ System.out.print("Digite valor 2: "); b = Short.parseShort(ent.readLine()); if (b < 0) System.out.println("Valor deve ser positivo"); else break; // quebra o lao quando o valor for correto }catch(IOException e){ System.out.println("Erro de leitura"); }catch(NumberFormatException e){ System.out.println("Leitura deve ser numrica"); } }while(true); // lao infinito c = a + b; System.out.println("Resultado = " + c); do{ try { System.out.print("Deseja realizar mais clculos (s/n)? "); continua = Character.toLowerCase(ent.readLine().charAt(0)); if (continua != 's' && continua != 'n') System.out.println("Digite s ou n"); } catch (IOException e) { System.out.println("Erro de leitura"); } }while(continua != 's' && continua != 'n'); } while (continua == 's'); } }

Exerccios:
1) Alterar o exerccio do Cardpio para que fique da seguinte forma: mostre o menu e leia o nome do cliente, o cdigo e a quantidade de cada item adquirido. A cada item digitado, fazer a pergunta: Deseja inserir mais algum item para esse cliente?. Se a resposta for negativa, calcular e mostrar o valor da conta a pagar por aquele cliente, assim: A conta do cliente FULANO deu xxx,xx. A seguir, perguntar: Deseja calcular a conta de mais algum cliente? Encerrar a aplicao apenas se a resposta for negativa. Realizar os testes em: cdigo do item, quantidade (positiva) e nas perguntas se quer continuar ou no.

Controle de Fluxo
40

Controle de fluxo a habilidade de ajustar a maneira como o nosso cdigo de programao realiza suas tarefas. Por meio de instrues especiais, essas tarefas podem ser executadas seletivamente, repetidamente ou excepcionalmente. Apesar de j termos utilizado algumas dessas estruturas no decorrer da apostila, iremos ver/revisar os seguintes itens:

Execuo Condicional if-else compacto ifs Aninhados switch..case Execuo com Repetio while do...while for break e continue

Execuo Condicional
A forma mais simples de controle de fluxo a instruo if-else. Ela empregada para executar seletivamente ou condicionalmente uma outra instruo mediante um critrio de seleo. Esse critrio dado por uma expresso, cujo valor resultante deve ser um dado do tipo booleano, isto , true ou false. Se esse valor for true, ento a outra instruo executada; se for false, a execuo da aplicao segue adiante. A sintaxe para essa instruo :
if ([condio]) [instruo ou bloco de instrues]; // Executado se a condio for true

Uma variao da instruo if-else permite escolher alternadamente entre duas outras instrues a executar. Nesse caso, se o valor da expresso condicional que define o critrio de seleo for true, ento a primeira das outras duas instrues executada, do contrrio, a segunda.
if([condio]) [instruo ou bloco de instrues] else [instruo ou bloco de instrues]; // Executado se a condio for true // Executado se a condio for false

Quando temos mais que uma instruo para um if ou um else, devemos coloc-las entre chaves, e chamamos isso de bloco de instrues: Exemplos: 1. {
System.out.print("x = "); System.out.println(x); } 2. { temp = y; y = x; x = temp; }

if-else Compacto

41

O if-else compacto no propriamente uma instruo, mas um operador que realiza avaliao seletiva de seus operandos, mediante o valor de uma expresso booleana semelhante da instruo if-else. Se essa expresso for true, ento um primeiro operando avaliado; se for false ento o segundo operando avaliado. A sua sintaxe :
[expresso condicional] ? [expresso 1] : [expresso 2]

Para melhor ilustrar o if-else compacto, consideremos a seguinte linha de programao:


y = x < 1 ? x*x : 2-x;

Este logicamente equivalente a:


if (x<1) then y = x*x; else y = 2-x;

ifs Aninhados
Freqentemente, desejamos que uma nica instruo (ou nico bloco de instrues) de uma lista seja executado mediante um dado critrio. Isso pode ser feito atravs do aninhamento ou acoplamento de vrias instrues if-else, do seguinte modo:
if ([condio 1]) [instruo ou bloco de else if ([condio 2]) [instruo ou bloco de else if ([condio 3]) [instruo ou bloco de .... else [instruo ou bloco de instrues] instrues] instrues] instrues]

A presena do ltimo else opcional. Vejamos um exemplo:


import java.io.*; public class TestaIfAninhado { public static void main(String args[]) { int x; BufferedReader ent = new BufferedReader(new InputStreamReader(System.in)); do{ try{ System.out.print("Digite valor: "); x = Integer.parseInt(ent.readLine()); break;// quebra o lao quando o valor for correto }catch(IOException e){ System.out.println("Erro de leitura"); }catch(NumberFormatException e){ System.out.println("Leitura deve ser numrica"); } }while(true); // lao infinito if (x > 0) System.out.println("O valor positivo");

42

else if(x < 0) System.out.println("O valor negativo"); else System.out.println("O valor igual a zero"); } }

switch...case
Observe o exemplo abaixo:
if (x == 1) System.out.println("Um"); else if(x == 2) System.out.println("Dois"); else if(x == 3) System.out.println("Trs"); else System.out.println("x nao esta no limite 1..3");

Para a situao apresentada no exemplo anterior, onde o teste se d exclusivamente em relao a igualdade de valores de uma nica varivel, possvel utilizar a instruo switch, cuja sintaxe a seguinte:
switch([variavel]) { case [constante 1]: [instruo ou bloco break; case [constante 2]: [instruo ou bloco break; . . . case [constante n]: [instruo ou bloco break; default: [instruo ou bloco }

de instrues] de instrues]

de instrues] de instrues]

A [variavel] avaliada e o seu valor comparado com as constantes distintas. Caso esse valor seja igual a uma dessas constantes, a respectiva instruo executada. necessrio ter um break em cada case, pois a condio de sada do switch. Caso no tenha, o fluxo invadir o prximo case. Se o valor for diferente de todas essas constantes, ento a instruo presente no rtulo default executado. Por exemplo:
switch(x) { case 1: System.out.println("Um"); break; case 2: System.out.println("Dois"); break; case 3: System.out.println("Trs");

43

break; default: System.out.println("x nao esta no limite 1..3"); } }

Nota Importante: O switch aceita apenas o teste com variveis inteiras e char. Demais tipos no so aceitos.

Exerccios:
1) Criar uma aplicao que faa a leitura de trs variveis short (positivas). Aps, mostrar o menu:
1-Mostrar os valores em ordem crescente 2-Mostrar os valores em ordem decrescente 3-Mostrar os valores na ordem menor-maior-intermediario 4-Sair

Ler uma varivel opcao (int entre 1 e 3) que ser a opo selecionada pelo usurio. Conforme a opo, realizar a tarefa. Aps mostrar o resultado, retornar ao menu. A opo 4 encerra a aplicao. Obrigatrio: Utilizar o if para a ordenao e o switch para testar a opo. 2) Criar uma aplicao que emule uma calculadora elementar. Ler um primeiro valor (float), um operador (char) e um segundo valor (float). Conforme o operador, que pode ser +, -, *, / (testar a validade), executar a operao e mostrar o resultado. Obrigatrio: Utilizar o switch para testar o operador. Aps executar, alterar a aplicao para que, aps o surgimento do resultado, seja solicitada a entrada de um novo operador e um novo valor, e assim por diante, at que seja digitado um f no operador, que a condio de trmino da aplicao.

Execuo com Repetio


Freqentemente, desejamos que uma tarefa seja executada repetidamente por uma aplicao enquanto uma dada condio seja verdadeira. Isso possvel atravs das instrues de repetio while, do...while e for.

Lao de iterao enquanto/faa


A instruo while avalia uma expresso condicional, que deve resultar no valor true ou false. Se o valor for true, ento a instruo subjacente executada; se a expresso for false, ento a instruo saltada e a execuo prossegue adiante. A diferena que aps executar a instruo subjacente, a expresso condicional novamente avaliada e seu resultado novamente considerado. Desse modo, a execuo da instruo subjacente se repetir, at que o valor da expresso condicional seja false. Observe, porm, que a expresso avaliada antes de uma possvel execuo da instruo subjacente, o que significa que essa instruo pode jamais ser executada. 44

while([condio]) [instruo ou bloco de instrues]

Por exemplo, no trecho a seguir, uma varivel iniciada com zero incrementada em um e mostrada enquanto for menor que cinco.
a = 0; while(a < 5) { a = a + 1; // ou a += 1 ou a++; System.out.println(a); }

Lao de iterao faa/enquanto


Um outro tipo de lao de repetio, similar ao enquanto/faa, o lao faa/enquanto. O A instruo dowhile tem a seguinte sintaxe:
do [instruo ou bloco de instrues] while([condio]);

Este tipo de lao de repetio executa a instruo e em seguida avalia a expresso condicional. A repetio ocorre se o valor dessa expresso for true. Se esse valor for false, a execuo prossegue adiante do while. Para o mesmo exemplo utilizado anteriormente, teramos o seguinte trecho de cdigo:
a = 0; do{ a = a + 1; System.out.println(a); }while(a < 5);

Exerccios:
1) Criar uma aplicao que leia dois valores m e n inteiros e calcula e mostra a soma dos n inteiros consecutivos a partir de m, inclusive. Utilizar o while. 2) Criar uma aplicao que leia dois valores a e b, inteiros e positivos (deve ter teste na leitura utilizar o do-while), e escreve os nmeros pares existentes entre o menor e o maior destes nmeros lidos, incluindo-os se forem pares. 3) Criar uma aplicao que gera e mostra os 4 primeiros nmeros perfeitos. Um nmero perfeito aquele que igual a soma dos seus divisores (Ex.: 6=1+2+3; 28=1+2+4+7+14).

Lao de iterao com contagem


Em certas situaes, precisamos de lao de repetio no qual alguma varivel usada para contar o nmero de iteraes. Para essa finalidade, temos o lao for. Sua sintaxe :
for ([expresso 1]; [condio]; [expresso 2]) [instruo ou bloco de instrues]

45

Onde [expresso 1] chamada expresso de inicializao, [condio] uma expresso condicional e [expresso 2] uma expresso qualquer a ser executado no final de cada iterao. O lao for acima equivalente a:
[expresso 1] while ([condio]) { [instruo ou bloco de instrues] [expresso 2] }

Isto que dizer que o lao for avalia inicialmente a expresso de inicializao. Em seguida, avalia a expresso condicional. Se o valor desta for true, ento a instruo executada, a segunda expresso avaliada em seguida, e finalmente o lao volta a avaliar novamente a expresso condicional. Do contrrio, se o valor da expresso for false, a execuo prossegue adiante do lao for. Para o mesmo exemplo utilizado nas instrues while, teramos o seguinte trecho de cdigo:
for(a = 1 ; a <= 5 ; a++) System.out.println(a);

Tanto a [expresso 1] quanto a [expresso 2] do lao for permitem acomodar mltiplas expresses, bastando separ-las por vrgula. Por exemplo, a soma de {1/n} para n=1,2, .., N pode ser obtida por:
for (soma = 0, n = 1; n <= N; n++) soma += 1/n;

ou ainda por
for(soma = 0, n = 1; n <= N; soma += 1/n, n++);

Exerccios:
1) A partir da sucesso a seguir, criar uma aplicao que leia o termo de ordem desejado, mostrando-o e logo aps solicitando se deseja mais algum termo. Utilizar o for.
ORDEM: 1 SUCESSO: -9 2 -7 3 -1 4 1 5 7 6 9 7 15 8... 17...

2) Refazer os exerccios 1 e 3 da pgina 15, utilizando o for para a manipulao dos vetores e matrizes.

break e continue
O comando break usado para interromper a execuo de um dos laos de iterao vistos acima ou de uma instruo switch. Essa instruo comumente utilizada para produzir a parada de um lao mediante a ocorrncia de alguma condio especfica, antes da chegada do final natural do lao. 46

Exemplo:
// Achar i tal que v[i] negativo for(i=0; i<n; i++) if(v[i] <0) break; if(i == n) System.out.println("Elemento negativo no encontrado."); eles System.out.println("Elemento negativo encontrado na posio " + i);

A instruo continue tem a funo de no executar os passos subsequentes daquela iterao (apenas essa), indo diretamente para a prxima iterao. Exemplo: No trecho a seguir, tem-se um lao de repetio que l valores para o clculo de uma mdia. Se o valor for menor que zero, o programa salta diretamente para a condio de controle, sem executar o resto das instrues. Se o valor for 1, o lao encerrado.
do{ System.out.print("Digite valor: "); val = Integer.parseInt(ent.readLine()); if (val == -1) // sada do lao break; if(val < 0) { // se val for negativo... printf("O valor deve ser positivo"); continue; // ...salta para o fim do lao... } num++; // ...e essas instrues... soma += val; // ...no so executadas! }while(1); printf("A mdia : %f",soma/num);

Exerccio:
1) Criar uma aplicao que pea para o usurio adivinhar um nmero escolhido aleatoriamente entre 1 e 20 (Utilize o Math.random()) Se o usurio digitar um nmero errado, o programa indica o novo intervalo do nmero procurado. Se o usurio acertar o nmero procurado, o programa mostra quantos palpites foram dados e encerra. Por exemplo:
O nmero procurado est entre 1 Palpite: 13 O nmero procurado est entre 1 Palpite: 5 O nmero procurado est entre 6 Palpite: 9 Parabns! Voc acertou o nmero e 20: e 12: e 12: em 3 tentativas.

Importante: Faa a aplicao em um lao infinito. Utilize o continue caso o usurio erre o palpite e break caso acerte (para encerrar).

Lanamento de Excees
47

Conforme visto na seo sobre manipulao de Excees, estas so eventos gerados automaticamente quando algo d errado em tempo de execuo. At agora aprendemos a manipular as excees, porm, possvel criarmos e lanarmos nossas prprias excees. Existem muitas situaes possveis de se lanar nossas prprias excees. Um caso clssico na verificao dos valores recebidos em mtodos setters. Se pegarmos o mesmo mtodo setMes apresentado na seo Encapsulamento, Setters e Getters, e validarmos o valor que recebido por parmetro, teramos como alternativa, caso o valor seja invlido, efetuar o lanamento de uma exceo com o nome MesInvalidoException. Uma vez lanada a exceo, no momento da utilizao do mtodo em alguma aplicao, haveria a necessidade (ou possibilidade) de efetuar a manipulao do erro a partir do try...catch, dando o tratamento desejado. Lembrando, o mtodo setMes, j com o teste de validade, ficaria assim:
public void setMes(int mes) { if (mes < 1 || mes > 12) // aqui dever acontecer o lanamento da exceo MesInvalidoException } this.mes = mes;

Antes de tudo, devemos criar a classe MesInvalidoException, que poder ser derivada de Exception ou RuntimeException, conforme queiramos que a exceo seja verificada ou no. Vamos conceituar essas situaes.

Excees verificadas e no verificadas


Toda exceo verificada deriva da classe Exception. No caso do setMes, poderamos criar uma classe derivada de Exception, assim:
public class MesInvalidoException extends Exception{ @Override public String toString(){ return getClass().getName() + ": Ms invlido"; } @Override public String getMessage(){ return "Ms invlido"; }

Perceba que os dois mtodos substituem os mtodos originais, onde a diferena entre o toString() e o getMessage() que, por conveno, o toString() apresenta, alm da mensagem, o nome da classe que lanou a exceo. No mtodo setMes, faremos o lanamento da exceo, atravs do throw, assim:
if (mes < 1 || mes > 12) throw new MesInvalidoException();

48

Pelo fato de ser uma exceo verificada, obrigatria a utilizao do throws aps a assinatura do mtodo. Isso vai indicar a obrigatoriedade de tratamento da exceo com try...catch onde esse mtodo for invocado. O mtodo, ento, ficar assim:
public void setMes(int mes) throws MesInvalidoException { if (mes < 1 || mes > 12) throw new MesInvalidoException(); this.mes = mes;

} Nesse caso, dentro da classe onde esse mtodo foi criado (ou em subclasses), se houver a utilizao dele, obrigatoriamente o mtodo que o utilizou ter que inserir o throws tambm. Como exemplo, temos o mtodo construtor, que, se receber um valor invlido, ir repassar diretamente para o set respectivo, para que ele faa o teste de validade. Dessa forma, o mtodo construtor ficaria assim:
public Data(int dia, int mes, int ano) throws MesInvalidoException { setDia(dia); setMes(mes); setAno(ano);

} E se houver lanamento de exceo nos outros mtodos, devemos inserir as outras classes de exceo criadas, separadas por vrgulas, assim:
public Data(int dia, int mes, int ano) throws MesInvalidoException, DiaInvalidoException

Em uma aplicao qualquer, ao utilizar o mtodo setMes, teramos o apontamento do seguinte erro: - Unhandled exception type MesInvalidoException (exceo MesInvalidoException no tratada). Assim, obrigatria a utilizao do try...catch para tratar a exceo. O cdigo a seguir j apresenta um lao para repetir a leitura do ms:
do{ System.out.print("Digite mes: "); m = Integer.parseInt(ent.readLine()); cal.setMes(m); break; }catch(IOException e){ System.out.println("Leitura invlida"); }catch(NumberFormatException e){ System.out.println("Leitura deve ser numrica"); }catch (MesInvalidoException e) { System.out.println(e.toString()); } }while(true); try{

49

A diferena da exceo verificada para a no verificada que essa segunda deriva da classe RuntimeException e no necessita da utilizao do throws. Dessa forma, no se torna obrigatrio o tratamento pelo try...catch na utilizao do mtodo. Porm, necessrio ter muito cuidado, pois, apesar de no ser obrigatrio o tratamento, se ocorrer o erro, a exceo ir ser lanada.

Exerccios :
1) Baseado nos exemplos vistos, altere o exerccio do Calendrio, criando rotinas de validao dos campos dia, mes e ano, lanando excees e as tratando na aplicao que dever ter o seguinte menu:
1- Mostra data formatada 2- Define novos valores 3- Verifica se ano Bissexto 4- Incrementa 1 dia 5- Decrementa 1 dia 6- Incrementa 1 ms 7- Decrementa 1 ms 8- Incrementa 1 ano 9- Decrementa 1 ano 10-Mostra o dia da semana 11-Finaliza

2) Baseado no exerccio da pgina 28 (classes de pessoas), validar o campo String cpf do mtodo setCPF da classe PessoaFisica a partir do algoritmo a seguir. O mtodo dever lanar uma exceo cpfInvalidoException caso os dgitos verificadores sejam invlidos. O primeiro teste a ser feito se o cpf tem 11 posies (a classe String possui o mtodo length que retorna o nmero de caracteres) Depois, fazer o teste do dgito verificador. Dica: pegar o substring do cpf, convertendo depois para inteiro, para que os clculos sejam realizados. Algoritmo para Validao do CPF: Descrio: O CPF (Cadastro de Pessoas Fsicas) serve para identificar cada indivduo no pas. O nmero do CPF composto de 11 dgitos, sendo os dois ltimos os dgitos de verificao. A frmula para verificar a validade do nmero do CPF simples e explicada a seguir. Tomando como exemplo o nmero 123.456.789-09. 1 Dgito Verificador Primeiro calculada a soma da multiplicao dos 9 primeiros dgitos por 10, 9, 8, ... , 3, 2, respectivamente. Ou seja:
soma = (1*10) + (2*9) + ... + (8*3) + (9*2);

Em seguida, se obtm o resto da diviso de Soma por 11, atravs do operador especfico, assim: 50

resultado = soma % 11;

Se resultado for igual 1 ou 0, ento o 1 dgito verificador 0. Caso contrrio, o 1 dgito verificador o resultado da subtrao 11 - resultado. 2 Dgito Verificador Primeiro calculada a soma da multiplicao dos 9 primeiros dgitos por 11, 10, 9, ... , 4, 3, respectivamente, e em seguida somado com (digito1*2), sendo que digito1 o valor encontrado para o 1 dgito verificador. Ou seja:
soma = (1*11) + (2*10) + ... + (8*4) + (9*3) + (Digito1*2);

O resto semelhante ao que foi feito anteriormente:


resultado = soma % 11;

Agora analisamos Resultado: Se resultado for igual 1 ou 0, ento o 2 dgito verificador 0. Caso contrrio, o 2 dgito verificador o resultado da subtrao 11 - resultado. No exemplo apresentado, (123.456.789-09) possui dgito verificador vlido.

Polimorfismo
Finalmente, uma caracterstica importante das classes reside no fato de que as subclasses de uma dada classe so consideradas do mesmo tipo de seu parente. Isto chamado polimorfismo. Este permite a realizao de uma mesma operao sobre diferentes tipos de classes, desde que mantenham algo em comum. Por exemplo, considere a classe Empregado e suas derivadas Chefe, TrabalhadorComissionado, TrabalhadorHorista e TrabalhadorPorPecas declaradas no estudo de caso abaixo. Apesar dessas subclasses serem diferentes, elas ainda so considerados empregados. Assim, qualquer coisa que fosse permitido fazer com uma instncia (i.e., um objeto) da classe Empregado, seria tambm permitida para as instncias das classes derivadas. O seguinte estudo de caso ilustra o polimorfismo entre essas classes permitindo que se verifique os vencimentos de cada empregado, independentemente do tipo de empregado.

Estudo de caso: sistema de folha de pagamento utilizando polimorfismo


A idia utilizar o polimorfismo para realizar clculos de folha de pagamento baseados no tipo de empregado. Utilizaremos uma superclasse Empregado. As sublcasses de Empregado so Chefe, pago com um salrio fixo semanal independente do nmero de horas trabalhadas , TrabalhadorComissionado, pago com um salrio bsico simples mais uma porcentagem sobre as vendas, TrabalhadorHorista, pago por hora com um adicional por hora extra e TrabalhadorPorPecas, pago pelo nmero de itens produzidos. Cada subclasse de empregado foi declarada final porque no pretendemos herdar delas novamente. Por fim, a classe 51

uma pequena aplicao utilizando as instncias particulares de cada tipo de empregado. Em notao UML, poderamos representar nosso projeto:
ExecutaEmpregados

Nota: A ferramenta utilizada para a representao se chama BlueJ version 1.2.0. Tal ferramenta um ambiente de desenvolvimento Java desenvolvido por pesquisadores da Monash University Austrlia e University of Southern Dinamarca. Disponvel em www.bluej.org. Antes de vermos o cdigo das classes do estudo de caso, precisamos de alguns conceitos: Declarando uma classe: A forma geral da declarao de uma classe a seguinte:
[modificadores] class [nome classe] extends [nome super] implements [nome interface]

onde as partes que aparecem em itlico so opcionais. Como podemos notar, h quatro diferentes propriedades de uma classe definidas por essa declarao:

Modificadores Nome de classe Superclasses Interfaces

Vamos ver em detalhes as trs primeiras propriedades. A primeira classe do estudo de caso a classe Empregado:
//Empregado.java //classe basica abstrata Empregado public abstract class Empregado { private String primeiroNome; // campos encapsulados private String ultimoNome; // construtor que inicia os campos com "" public Empregado() { this.primeiroNome = ""; this.ultimoNome = ""; } // Construtor que recebe valores a partir da instanciao // ESSE CONSTRUTOR UMA SOBREPOSIO (OVERLOAD) DE MTODO

52

// DO PRIMEIRO CONSTRUTOR public Empregado(String primeiroNome, String ultimoNome) { setPrimeiroNome(primeiroNome); setUltimoNome(ultimoNome); } public String getPrimeiroNome() { return primeiroNome; } public void setPrimeiroNome(String primeiroNome) { this.primeiroNome = primeiroNome; } public String getUltimoNome() { return ultimoNome; } public void setUltimoNome(String ultimoNome) { this.ultimoNome = ultimoNome; } // Retorna o primeiro e o ultimo nome public String toString() { return this.primeiroNome + ' ' + this.ultimoNome; } // mtodo abstrato que deve ser implementado para cada classe // derivada de Empregado pelos quais os objetos serao instanciados public abstract double vencimentos(); }

Percebe-se a utilizao do modificador abstract para essa classe, o que indica que ela no poder ser instanciada, apenas derivada. Alm disso, ela public, podendo ser utilizada livremente por qualquer outra classe Java. Logo a seguir temos a declarao de duas variveis do tipo String privadas. Alguns conceitos so importantes aqui: static: Um campo static compartilhado por todas as instncias de uma classe, isto , h um nico valor para esse campo, independentemente da quantidade de instncias existentes, mesmo que no haja nenhuma.

um modificador final precedendo um campo declara esse campo como uma constante. Seu valor no pode mudar durante a execuo do programa. Por isso, necessrio que haja uma inicializao de campo. O uso de constantes dentro de um programa torna-o mais legvel. Por exemplo:
final int MaxDimen = 10;

final:

Voltando a nossa classe Empregado, as variveis


private String primeiroNome; private String ultimoNome;

so privadas, o que indica que elas so visveis apenas dentro do seu cdigo, no podendo ser acessadas em classes derivadas, por exemplo. 53

O mtodo
public Empregado( String primeiro, String ultimo ) {

diferente dos mtodos convencionais, pois ele possui o mesmo nome da classe. Quando o mtodo possui o mesmo nome da classe, so chamados de Constructors. Os construtores so mtodos muito especiais, a comear pela sua sintaxe declarativa, e tambm por suas propriedades e finalidade nicas. Por exemplo, o construtor da classe Empregado vista acima o seguinte:
public Empregado( String primeiro, String ultimo ) { primeiroNome = primeiro; ultimoNome = ultimo; }

Sua nica finalidade permitir a inicializao dos objetos que sero criados futuramente, com o primeiro e o segundo nome do empregado. Isso ser feito no momento da instanciao. Alis, esta a principal finalidade dos construtores: atribuir a um objeto um estado inicial, apropriado ao processamento subseqente. Nota: usual declarar os construtores como pblicos. Isto porque, se eles tiverem um nvel de acesso inferior ao da classe propriamente dita, outra classe ser capaz de declarar uma instncia dessa classe, mas no ser capaz de realizar ela mesma a instanciao, isto , no poder usar o operador new para essa classe. H situaes, porm, em que essa caracterstica desejvel. Deixando seus construtores como privativos, permite a outras classes usar mtodos estticos, sem permitir que elas criem instncias dessa classe. Quando nenhum construtor declarado explicitamente, um construtor vazio provido implicitamente. Por exemplo, se no tivssemos especificado um construtor na classe Empregado, este seria o construtor default:
Empregado() { }

Os construtores no podem ser declarados com os modificadores: native, abstract, static, synchronized ou final. Imaginem que tivssemos a seguinte situao: os nomes das variveis recebidas como parmetros pelo construtor serem os mesmos das variveis da classe, assim:
public Empregado( String primeiroNome, String ultimoNome ) { primeiroNome = primeiroNome; ultimoNome = ultimoNome; }

um mtodo pblico que retorna o nome e o sobrenome separados por um espao. O mtodo
vencimentos() public abstract double vencimentos();

54

definido como abstract porque no faz sentido fornecer uma implementao desse mtodo na classe Empregado, pois precisamos saber o tipo de empregado para podermos calcular o salrio de cada um. Ao colocar o modificador abstract, estamos indicando que forneceremos uma implementao em cada subclasse concreta, mas no na prpria superclasse. A prxima classe a ser implementada a subclasse de Empregado, chamada Chefe. A herana determinada pela palavra chave extends. A classe Chefe, como todas outras que sero derivadas de Empregado so definidas como final porque no pretendemos herdar delas novamente. A varivel salarioSemanal declarada como privativa classe.
// Chefe.java // Classe Chefe derivada de Empregado public class Chefe extends Empregado{ private double salarioSemanal; public Chefe(){ super(); //invoca o construtor da classe pai (Empregado), // que ir iniciar os campos nome e sobrenome com "" this.salarioSemanal = 0.0; } // overload (sobreposio) do primeiro construtor public Chefe(String primeiroNome,String ultimoNome,double salarioSemanal){ super(primeiroNome,ultimoNome); setSalarioSemanal(salarioSemanal); } public double getSalarioSemanal() { return salarioSemanal; } public void setSalarioSemanal(double salarioSemanal) { this.salarioSemanal = salarioSemanal; } // aqui acontece a substituio (override) do mtodo abstrato // vencimentos() da classe pai (Empregado) @Override public double vencimentos() { return this.salarioSemanal; } // substituio (override) do mtodo toString() da classe pai(Empregado) @Override public String toString(){ return "Chefe: " + super.toString(); } }

O construtor da classe recebe como parmetros um nome, um sobrenome e um salrio semanal e passa o nome e sobrenome para o construtor da superclasse, atravs da especificao super. Alm disso utiliza o mtodo setSalarioSemanal para atribuir um novo valor a vriavel salarioSemanal.
public Chefe( String primeiro, String ultimo, double s) {

55

super( primeiro, ultimo ); setSalarioSemanal( s ); }

// chama o constructor da superclasse

Referente a especificao super, ela prov acesso a partes de uma superclasse a partir de uma subclasse. Quando colocamos apenas a palavra-chave super, indicamos que queremos utilizar o construtor da superclasse, mas a utilizao dessa especificao tambm muito til quando estamos sobrepondo um mtodo. Poderamos reescrever o mtodo Desligar da classe ComputadorSeguro do seguinte modo:
class ComputadorSeguro extends Computador { private boolean executando = true; public void Desligar() { if ( executando ) System.out.println("H programas rodando. No desligue!"); else super.Desligar(); } }

Note que a chamada super.Desligar() corresponde ao mtodo Desligar declarado na superclasse Computador. O mtodo vencimentos()
public double vencimentos() { return salarioSemanal; }

declarado nessa classe vai conter o cdigo referente ao clculo do salrio desse tipo de empregado. Todas outras subclasses possuem um mtodo vencimentos(), com seus clculos especficos, justificando a utilizao do mtodo abstract na classe Empregado. Por fim, o mtodo toString()
public String toString() { return "Chefe: " + super.toString(); }

retorna um string contendo o tipo do empregado seguido pelo retorno do mtodo toString() da superclasse Empregado. Pode parecer estranho ter um mesmo nome de mtodo na superclasse e na subclasse. Isso possvel por causa de uma tcnica chamada sobreposio. No permitido declarar em uma mesma classe dois mtodos com o mesmo nome e mesma lista de argumentos. Entretanto, uma das finalidades de permitir a derivao de classes atribuir a elas novas funcionalidades. Isto possvel acrescentando-se novos mtodos s subclasses. Mas tambm possvel subrepor qualquer dos mtodos existentes na superclasse, declarando o novo mtodo na subclasse exatamente com o mesmo nome e lista de argumentos, como consta na superclasse. Por isso, o mtodo toString() pode ser reescrito em cada subclasse da superclasse Empregado. Nota: A sobreposio somente acontece quando o novo mtodo declarado com exatamente o mesmo nome e lista de argumentos que o mtodo existente na superclasse. Alm disso, a 56

sobreposio no permite que o novo mtodo tenha mais protees do que o mtodo original. Por exemplo, toString() foi declarado como public na superclasse, no podendo ser declarado como private na subclasse. As prximas trs classes a serem implementadas so as subclasses TrabalhadorComissionado, TrabalhadorHorista e TrabalhadorPorPecas. Da mesma forma que a classe Chefe, essas possuem variveis da classe, construtor, mtodos particulares, o mtodo toString() sobreposto e o mtodo vencimentos(). A classe TrabalhadorComissionado fica assim:
// TrabalhadorComissionado.java // Classe TrabalhadorComissionado derivada de Empregado public class TrabalhadorComissionado extends Empregado { private double salario; // salario base por semana private double comissao; // comissao por item vendido private int quantidade; // total de itens vendidos por semana public TrabalhadorComissionado() { super(); // invoca o construtor da classe pai (Empregado), // que ir iniciar os campos nome e sobrenome com "" this.salario = 0.0; this.comissao = 0.0; this.quantidade = 0; } // overload (sobreposio) do primeiro construtor public TrabalhadorComissionado(String primeiroNome, String ultimoNome, double salario, double comissao, int quantidade) { super(primeiroNome, ultimoNome); setSalario(salario); setComissao(comissao); setQuantidade(quantidade); } public double getSalario() { return salario; } public void setSalario(double salario) { this.salario = salario; } public double getComissao() { return comissao; } public void setComissao(double comissao) { this.comissao = comissao; } public int getQuantidade() { return quantidade; } public void setQuantidade(int quantidade) {

57

this.quantidade = quantidade;

// aqui acontece a substituio (override) do mtodo abstrato // vencimentos() da classe pai (Empregado) @Override public double vencimentos() { return this.salario + this.quantidade * this.comissao; } // substituio (override) do mtodo toString() da classe pai(Empregado) @Override public String toString(){ return "Trabalhador Comissionado: " + super.toString(); }

A classe TrabalhadorHorista fica assim: // TrabalhadorHorista.java // Classe TrabalhadorHorista derivada de Empregado public class TrabalhadorHorista extends Empregado{ private double valorHora; // valor que recebe por hora private double horas; // horas trabalhadas public TrabalhadorHorista(){ super(); //invoca o construtor da classe pai (Empregado), // que ir iniciar os campos nome e sobrenome com "" this.valorHora = 0.0; this.horas = 0.0; } // overload (sobreposio) do primeiro construtor public TrabalhadorHorista(String primeiroNome, String ultimoNome, double valorHora, double horas){ super(primeiroNome,ultimoNome); setValorHora(valorHora); setHoras(horas); } public double getValorHora() { return valorHora; } public void setValorHora(double valorHora) { this.valorHora = valorHora; } public double getHoras() { return horas; } public void setHoras(double horas) { this.horas = horas; } // aqui acontece a substituio (override) do mtodo abstrato // vencimentos() da classe pai (Empregado) @Override

58

public double vencimentos() { return this.valorHora * this.horas; } // substituio (override) do mtodo toString() da classe pai(Empregado) @Override public String toString(){ return "Trabalhador Horista: " + super.toString(); }

A classe TrabalhadorPorPecas fica assim: // TrabalhadorPorPecas.java // Classe TrabalhadorPorPecas derivada de Empregado public class TrabalhadorPorPecas extends Empregado { private double valorPorPeca; // valor recebido por peca produzida private int quantidade; // quantidade de pecas public TrabalhadorPorPecas() { super(); // invoca o construtor da classe pai (Empregado), // que ir iniciar os campos nome e sobrenome com "" this.valorPorPeca = 0.0; this.quantidade = 0; } // overload (sobreposio) do primeiro construtor public TrabalhadorPorPecas(String primeiroNome, String ultimoNome, double valorPorPeca, int quantidade) { super(primeiroNome, ultimoNome); setValorPorPeca(valorPorPeca); setQuantidade(quantidade); } public double getValorPorPeca() { return valorPorPeca; } public void setValorPorPeca(double valorPorPeca) { this.valorPorPeca = valorPorPeca; } public int getQuantidade() { return quantidade; } public void setQuantidade(int quantidade) { this.quantidade = quantidade; } // aqui acontece a substituio (override) do mtodo abstrato // vencimentos() da classe pai (Empregado) @Override public double vencimentos() { return this.valorPorPeca * this.quantidade; } // substituio (override) do mtodo toString() da classe pai(Empregado)

59

@Override public String toString(){ return "Trabalhador por peas: " + super.toString(); } }

Finalmente, a classe ExecutaEmpregados uma aplicao que declara instncias de teste para a estrutura definida. O mtodo main() comea declarando a referncia a Empregado chamada ref.
// ExecutaEmpregados.java public class ExecutaEmpregado { public static void main(String[] args) { Chefe objCh = new Chefe("Maria","Souza",1565.15); //System.out.println(objCh.toString()); //System.out.println(objCh.vencimentos()); TrabalhadorComissionado objTC = new TrabalhadorComissionado("Mario","Fernandez",520.33,0.5,10000); //System.out.println(objTC.toString()); //System.out.println(objTC.vencimentos()); TrabalhadorHorista objTH = new TrabalhadorHorista("Claudionei","Macedo",15.10,200); //System.out.println(objTH.toString()); //System.out.println(objTH.vencimentos()); TrabalhadorPorPecas objTP = new TrabalhadorPorPecas("Josevaldo","Silva",0.63,5450); //System.out.println(objTP.toString()); //System.out.println(objTP.vencimentos()); Empregado objEmpregado = null; // criao da referncia classe pai short opcao; do{ System.out.println("Escolha o tipo do Empregado: "); System.out.println("1-Chefe"); System.out.println("2-Trabalhador Comissionado"); System.out.println("3-Trabalhador Horista"); System.out.println("4-Trabalhador Por Pecas"); System.out.println("5-Encerrar"); do{ try{ System.out.print("Digite opo: "); opcao = Short.parseShort(ent.readLine()); if (opcao < 1 || opcao > 4) System.out.println("Opo invlida"); else break; }catch(IOException e){ System.out.println("Leitura invlida"); }catch(NumberFormatException e){ System.out.println("Leitura deve ser numrica"); } switch (opcao){ case 1: objEmpregado = objCh; break;

60

case 2: objEmpregado = objTC; break; case 3: objEmpregado = objTH; break; case 4: objEmpregado = objTP; break; } // aqui o espao para fazer uma aplicao // especfica para o empregado selecionado // utilizando o polimorfismo System.out.println(objEmpregado.toString()); System.out.println(objEmpregado.vencimentos()); }while(opcao != 5); } }

61

Você também pode gostar