Sie sind auf Seite 1von 149

Apostila de Java

Introduo
Baseada nos 7 Primeiros Captulos do
Livro Core Java Fundamentals
de Cay S. HorstMann e Gray Cornel
Prof. Carlos Ribeiro
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 2
ndice
INTRODUO.............................................................................................................................................5
O Que Java................................................................................................................................................5
Como Compilar e Executar um Programa Java...........................................................................................8
Applications.............................................................................................................................................8
Java Bemvindo ....................................................................................................................................8
Applets.....................................................................................................................................................9
IDENTIFICADORES, PALAVRAS-CHAVE, TIPOS E OPERADORES............................................13
Comentrios...............................................................................................................................................15
Identificadores ...........................................................................................................................................15
Palavras-Chave..........................................................................................................................................15
Tipos de Dados..........................................................................................................................................16
Lgico boolean...............................................................................................................................16
Texto char e String......................................................................................................................16
Char ...................................................................................................................................................16
Strings................................................................................................................................................17
Inteiros byte, short, int e long.................................................................................................20
Pontos Flutuantes float e double .............................................................................................21
Float...................................................................................................................................................21
Double ...............................................................................................................................................22
Variveis....................................................................................................................................................22
Designaes e Inicializaes .....................................................................................................................23
Converses entre Tipos Numricos ...........................................................................................................23
Constantes .................................................................................................................................................24
Variveis de Classe....................................................................................................................................25
Operadores.................................................................................................................................................26
Exponenciao...........................................................................................................................................27
Operadores de Incremento e Decremento..................................................................................................27
Operadores Relacionais e Boleanos...........................................................................................................27
Parnteses e a Hierarquia dos Operadores.................................................................................................28
ENTRADA DE DADOS E FORMATAO DA SADA........................................................................29
Lendo Dados..............................................................................................................................................29
Formatando a Sada ...................................................................................................................................30
PRINCIPAIS ESTRUTURAS DE PROGRAMAO EM JAVA.........................................................33
Controle de Fluxo......................................................................................................................................33
Comandos Condicionais ........................................................................................................................33
Loops Indeterminados ...........................................................................................................................35
Loops Determinados..............................................................................................................................36
O Comando Switch................................................................................................................................37
O Comando Break .................................................................................................................................38
Mtodos de Classes (Funes Definidas pelo Usurio).............................................................................40
Recursividade ............................................................................................................................................43
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 3
ARRAYS ......................................................................................................................................................44
Copiando Arrays........................................................................................................................................45
Arrays como Argumentos..........................................................................................................................46
O Mtodo Lenght ......................................................................................................................................46
Retornando um Array................................................................................................................................48
Arrays Multidimensionais .........................................................................................................................49
Determinando o nmero de linhas e de colunas ........................................................................................51
OBJETOS E CLASSES ..............................................................................................................................52
Terminologia .............................................................................................................................................53
Como Definir uma Classe..........................................................................................................................54
Relacionamentos entre Classes..................................................................................................................60
Diferenas entre a OOP e as Tcnicas Tradicionais de Desenvolvimento de Software ............................62
Variveis do Tipo Objeto ..........................................................................................................................62
A Classe GregorianCalendar .....................................................................................................................64
Alguns Mtodos Definidos para a Classe GregorianCalendar...............................................................65
Mtodos para Acesso e Mutao...............................................................................................................67
Objetos como Argumentos de Funes .....................................................................................................68
A Classe Date ............................................................................................................................................70
Construindo suas Prprias Classes ............................................................................................................72
Construtores...............................................................................................................................................75
Mtodos Privados ......................................................................................................................................78
Mtodos Construtores................................................................................................................................78
Construtores Default..............................................................................................................................80
Overloading...............................................................................................................................................80
O Objeto this .............................................................................................................................................83
O Mtodo toString.....................................................................................................................................84
Blocos de Inicializao..............................................................................................................................85
Mtodos e Campos Estticos.....................................................................................................................86
Como Inicializar um Campo Esttico........................................................................................................86
Como Compilar Programas .......................................................................................................................87
Packages ....................................................................................................................................................88
Utilizando Packages ..............................................................................................................................89
Como o Compilador Localiza os Packages ...........................................................................................89
O Escopo de um Package ......................................................................................................................89
Polimorfismo.............................................................................................................................................97
Como Impedir a Herana...........................................................................................................................99
Instanceof ................................................................................................................................................100
Casting.....................................................................................................................................................100
Classes do tipo Abstract.......................................................................................................................105
Mtodos do Tipo Protected......................................................................................................................114
Object: A Superclasse Csmica...............................................................................................................114
Vectors.....................................................................................................................................................120
Trabalhando com um Vector Existente ...................................................................................................122
Acessando um Elemento de um Vector...................................................................................................123
Inserindo e Removendo Elementos de um Vector...................................................................................126
Objetos Empacotadores ...........................................................................................................................131
Convertendo Strings em Nmeros...........................................................................................................133
A Classe Class (Identificao de Tipo em Tempo de Execuo) ............................................................134
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 4
INTERFACES E INNER CLASSES .......................................................................................................137
Utilizando uma Superclasse do tipo Abstract ..........................................................................................137
Utilizando uma Interface .........................................................................................................................140
Propriedades das Interfaces .....................................................................................................................143
A Interface Cloneable..............................................................................................................................145
BIBLIOGRAFIA.......................................................................................................................................149
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 5
INTRODUO
O Que Java
Uma linguagem de programao desenvolvida com os seguintes objetivos:
Criar uma linguagem orientada a objetos.
Prover um ambiente interpretado por duas razes:
Aumentar a velocidade do desenvolvimento eliminando a necessidade do ciclo
compilao-ligao-carga-teste.
Tornar o cdigo portvel.
Eliminar prticas de programao que afetam a robustez do cdigo.
Aritmtica de ponteiro.
Alocao e desalocao de memria.
Permitir que programas executem mais de uma thread.
A arquitetura de Java foi desenvolvida para alcanar estes objetivos. As seguintes
caractersticas da linguagem foram elaboradas para atingir estes objetivos:
A Mquina Virtual Java
Garbage collection
Code security
A Mquina Virtual Java
A Especificao da Mquina Virtual Java define o termo Mquina Virtual Java (JVM)
assim:
Uma mquina imaginria que implementada emulando-a atravs de software
em uma mquina real. O cdigo a ser executado por uma Mquina Virtual Java
armazenado em um arquivo .class. Cada arquivo .class contm o cdigo para no mximo
uma classe pblica.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 6
O cdigo a ser executado por uma JVM consiste de um cdigo pr-compilado
denominado byte code. A maior parte da checagem de tipos em Java ocorre em tempo de
compilao, isto , no momento em que o byte code gerado.
Qualquer interpretador Java compatvel deve ser capaz de executar qualquer programa
com arquivos .class que estejam de acordo com o formato especificado para estes
arquivos na Especificao da Mquina Virtual Java.
Garbage Collection (Coleta de Lixo)
Em linguagens como C / C++ o programador fica responsvel por liberar toda a memria
alocada ao longo da execuo do programa. Programas que no desalocam memria
podem eventualmente travar quando no h mais memria no sistema para alocar.
Java remove do programador a responsabilidade de liberar a memria alocada ao longo
da execuo de um programa. A JVM prov uma thread (executando em background)
que registra toda a alocao de memria e mantm um contador do nmero de referncias
para cada ponteiro de memria. Quando a JVM encontra-se ociosa, a thread de coleta de
lixo checa para ver se existem ponteiros de memria para os quais o nmero de
referncias caiu a zero. Neste caso a memria liberada pelo coletor de lixo. A coleta de
lixo ocorre automaticamente durante o tempo de vida de um programa Java e elimina a
necessidade de desalocao de memria por parte do programador.
Code Security (Segurana de Cdigo)
Arquivos Java so compilados no sentido de que so convertidos de um formato texto
(como so escritos) em um conjunto de cdigos (byte code) independente de mquina.
Em tempo de execuo, os byte codes que formam um programa Java so carregados,
verificados, e ento executados pelo interpretador. O interpretador possui duas tarefas:
executar o byte code Java e efetuar as chamadas apropriadas ao sistema para executar o
byte code no hardware disponvel.
Em alguns ambientes Java, uma poro do cdigo java verificado compilado para
cdigo de mquina nativo e executado diretamente na plataforma do hardware. (Nestes
ambientes, costumam ser compiladas as pores de cdigo executadas com maior
freqncia.)
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 7
O Interpretador Java
O interpretador Java possui trs tarefas principais:
Carregar o cdigo Esta tarefa executada pelo Class Loader.
Verificar o cdigo Tarefa executada pelo Byte Code Verifier.
Executar o cdigo Tarefa executada pelo Runtime Interpreter.
Class Loader
O Class Loader carrega todas as classes necessrias para executar o programa. O Class
Loader adiciona segurana separando os name spaces das classes do sistema de arquivos
local e daquelas importadas atravs da rede. Isto limita qualquer aplicao cavalo de
tria.
Byte Code Verifier
Um cdigo Java passa por vrios testes antes de ser efetivamente executado. O Byte Code
Verifier testa o formato de fragmentos de cdigo procurando por cdigo ilegal.
O Byte Code Verifier verifica se o cdigo (byte code) respeita a especificao da JVM e
no viola a integridade do sistema. Se o verificador completa a verificao sem retornar
uma mensagem de erro, ento voc pode estar certo de que:
As classes seguem fielmente as especificaes da JVM.
No h violaes de restries de acesso.
Os tipos dos parmetros esto corretos.
Nenhuma converso ilegal ser feita, como converter inteiros em ponteiros.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 8
Como Compilar e Executar um Programa Java
Applications
1. No Ambiente DOS
Javac Bemvindo.java
Java Bemvindo
O programa javac compila o arquivo Bemvindo.java na classe Bemvindo.class e o
programa java interpreta o bytecode que o compilador gerou, isto , o interpretador
executa o arquivo Bemvindo.class.
Exemplo 1
Este programa simplesmente exibe uma mensagem na console (janela DOS).
public class Bemvindo
{ public static void main(String[] args)
{ String[] vetor = new String[3];
vetor[0] = "Meu Primeiro Programa";
vetor[1] = "Que Emoo!!!";
vetor[2] = "Carlos";
int i;
for (i = 0; i < vetor.length; i++)
System.out.println(vetor[i]);
}
}
2. Utilizando o Kawa
Iniciar o Kawa
Abrir o arquivo Bemvindo.java
Clicar no boto Compile para executar o Compilador Java
Clicar no boto Run Java para executar o programa
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 9
Applets
O programa apresentado na pgina anterior uma Java Application, isto , um
programa stand alone. No entanto, possvel executar Applets dentro de um Web
browser. Veremos, a seguir como executar uma applet a partir da linha de comando e
atravs do applet viewer que vem com o JDK.
1. No Ambiente DOS
Javac BemvindoApplet.java
appletviewer BemvindoApplet.html
O primeiro comando chama o compilador java que gera o arquivo
BemvindoApplet.class.
J o segundo comando executa uma ferramenta que vem com o JDK que nos permite
testar a Applet sem a necessidade de um browser (Web).
O contedo do arquivo .html vem a seguir:
(Este cdigo necessita ser convertido, para chama-lo atravs do browser. Para ver a
applet com o appletviewer utiliza-se o arquivo html sem converso.)
<HTML>
<TITLE>Bemvindo</TITLE>
<BODY>
Applet Bemvindo.
<APPLET CODE="BemvindoApplet.class" WIDTH=180 HEIGHT=180>
</APPLET>
</BODY>
</HTML>
Observe que o tag APPLET indica que o applet viewer dever carregar a applet cujo
cdigo se encontra no arquivo Bemvindo.class. O applet viewer ignora todos os
demais tags existentes neste arquivo. H uma srie de tags que permitem que o
browser carregue o java plug-in e exiba o texto HTML juntamente com a applet,
como um objeto embutido. Caso voc possua o java plug-in instalado, voc poder
ver esta pgina com o Netscape ou com o Internet Explorer. O java plug-in localiza o
ambiente de run-time Java corrente e o utiliza para carregar e exibir a applet.
Infelizmente, objetos embutidos so tratados diferentemente pelo Netscape e pelo
Internet Explorer. Para exibir a applet em ambos os browsers, a pgina acima
necessita ser convertida. Aps o processo de converso um cdigo javascript ser
acrescentado com o objetivo de detectar qual browser est sendo utilizado para que
sejam executados os tags apropriados para exibir a applet.
Note que os botes no funcionam no applet viewer. O applet viewer serve apenas
para executar um teste rpido da applet.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 10
2. Utilizando o Kawa
Tambm possvel compilar applets com o Kawa e compilar e executar applets com
o TextPad. Para executar uma applet com o TextPad selecione Compile e aps
Run.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 11
Documentao da API Java
At aqui vimos todos os termos bsicos que java utiliza para descrever seus mtodos,
classes e interfaces. Uma vez sentindo-se confortvel com estas informaes, com
freqncia, voc consultar a documentao das APIs que vem com o JDK.
Com o seu web browser aponte para c:\jdk1.2\docs\api\index.html
A figura abaixo apresenta 3 janelas: Uma pequena janela no topo a esquerda mostra todos
os packages disponveis. Clique em um package e todas as classes existentes neste
package aparecero na janela inferior esquerda. Clique no nome de uma classe e a
documentao referente a esta API ser exibida na janela maior direita.
No topo da documentao de cada classe aparece o nome da classe e a cadeia de herana
desta classe, seguido de uma discusso (mais ou menos til) a respeito da classe. A seguir
vem um resumo de todos os campos pblicos e protected, e de todos os construtores e
mtodos.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 12
No topo de cada pgina h um conjunto de links interessantes: clique em Tree para
obter uma viso de todas as classes neste package. Clique em all packages para obter
uma lista de todos os packages.
E para obter uma descrio detalhada a respeito de campos e mtodos clique em seus
nomes.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 13
IDENTIFICADORES, PALAVRAS-CHAVE, TIPOS E OPERADORES
Infelizmente, em Java, no simples escrever um programa que utiliza uma interface
grfica. Como nosso objetivo, no momento, escrever programas simples, em vez de
utilizar uma interface grfica (que seria complicado) vamos escrever programas que
simplesmente lem dados do teclado e enviam dados para a console (uma janela DOS, no
windows).
Como efetuar a leitura de dados diretamente do teclado no muito fcil, vamos utilizar
uma classe para este fim sem nos preocuparmos como ela funciona.
Um Simples Programa Java
public class PrimeiroExemplo
{ public static void main (String[] args)
{ System.out.println ("Al Mundo!");
}
}
ou
public class SegundoExemplo
{ public static void main(String[] args)
{ int i;
for (i = 0; i < args.length; i++)
System.out.println(args[i]);
}
}
Observaes sobre o programa PrimeiroExemplo:
Java case sensitive. Se voc digitar Main em vez de main o programa no
compilar.
A palavra-chave public denominada um access modifier. Um modifier controla
que partes de um programa podem utilizar este cdigo.
A palavra-chave class para nos lembrar que tudo em java ocorre dentro de uma
classe.
Aps a palavra-chave class vem o nome da classe. O nome de uma classe deve
comear com uma letra. Os demais caracteres devem ser letras ou dgitos. O tamanho
ilimitado. Palavras reservadas no podem ser utilizadas como nome de classe.
preciso criar um arquivo com o mesmo nome da classe pblica com a extenso
.java. Logo, o cdigo acima deve ser armazenado em um arquivo denominado
PrimeiroExemplo.java.
Para compilar este programa digite: javac PrimeiroExemplo.java
E para execut-lo digite: java PrimeiroExemplo (no digite a extenso .class)
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 14
O interpretador java sempre comea a execuo de um programa pelo mtodo
denominado main. Naturalmente voc pode adicionar seus prprios mtodos a uma
classe e cham-los a partir do mtodo main.
Chaves {um bloco} so utilizadas para delimitar as partes (blocos) do seu programa.
A palavra-chave static indica que o mtodo no opera sobre objetos. O mtodo main
em Java sempre static. E a palavra-chave void indica que o mtodo no retorna um
valor.
Com relao ao fragmento:
{ System.out.println ("Al Mundo!");
}
As chaves indicam o incio e o fim do corpo de um mtodo.
Em Java todo comando deve terminar com um ponto e vrgula. O ponto e vrgula
no um separador de comandos como em pascal, mas um terminador de
comandos.
No comando acima estamos utilizando o objeto System.out e pedindo para ele
utilizar o mtodo println. Java sempre utiliza a sintaxe:
objeto.mtodo(parmetros).
O mtodo println trabalha com um String e o exibe na console.
Observe que Java utiliza aspas duplas para strings.
Mtodos em Java, assim como funes em qualquer linguagem de programao,
podem utilizar zero, um ou mais argumentos. At mesmo o mtodo main aceita
que o usurio digite na linha de comando seus argumentos.
Mesmo que um mtodo possua zero argumentos, devero ser utilizados parnteses
vazios.
Existe um mtodo denominado print em System.out que no adiciona um caracter
de nova linha ao string.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 15
Comentrios
H trs maneiras de se colocar um comentrio em um programa java:
// Primeira forma. Utilizada quando o comentrio no excede uma
linha.
/* Segunda forma: deve ser utilizada quando o comentrio longo e
ocupa vrias linhas */
/** Terceira forma: Deve ser utilizada quando se deseja gerar
documentao automaticamente. H um utilitrio denominado javadoc
para este fim. */
Este ltimo tipo de comentrio, quando colocado imediatamente antes de uma
declarao (de uma varivel ou mtodo), indica que o comentrio deve ser includo em
qualquer documentao gerada automaticamente. (Arquivos HTML gerados pelo
comando JAVADOC). Estes comentrios aparecem como uma descrio do item
declarado.
Identificadores
Na linguagem Java um identificador comea com uma letra, um underscore (_), ou com o
smbolo $. Caracteres subsequentes tambm podem conter dgitos. Identificadores so
case sensitive e no possuem tamanho mximo.
Palavras-Chave
abstract do implements private throw
boolean double import protected throws
break else instanceof public transient
byte extends int return true
case false interface short try
catch final long static void
char finally native super volatile
class float new switch while
continue for null synchronized
default if package this
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 16
Observaes:
1. Em Java os literais true, false e null so em letras minsculas e no em letras
maisculas como em C++. Estritamente falando eles no so palavras-chave e sim
literais.
2. goto e const so palavras chave mas no so utilizadas em java.
3. No existe o operador sizeof. O tamanho e a representao de todos os tipos so fixos
e no so dependentes de implementao.
Tipos de Dados
Java possui oito tipos de dados primitivos e um tipo especial. Estes tipos podem ser
utilizados como valores de literais ou em variveis. Estes tipos podem ser considerados
em quatro categorias: lgico, texto, inteiro e ponto flutuante.
Lgico boolean
Booleanos em java possuem dois valores literais: true e false. No h como
converter booleanos em inteiros e vice-versa. Em C / C++ valores numricos podem ser
interpretados como valores lgicos (0 false e no 0 true). Isto no permitido em
Java.
Texto char e String
Char
Caracteres isolados so representados utilizando-se o tipo char. Um char representa um
caracter Unicode utilizando um nmero sem sinal de 16 bits na faixa de 0 a 2
16
-1. Um
literal do tipo char deve aparecer entre plics.
a
\t um tab
\n linefeed
\u???? um caracter Unicode especfico. ???? deve ser substitudo por
exatamente 4 dgitos hexadecimais. Ex. \u0041 o caracter A.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 17
Strings
O tipo String, que no primitivo, encontra-se definido na biblioteca standard da
linguagem. utilizado para representar seqncias de caracteres. Os caracteres em si so
Unicode. Um String literal deve aparecer entre aspas e so seqncias de caracteres. Cada
conjunto de caracteres entre aspas uma instncia da classe String.
Exemplos:
String e = ; // Observe que como String uma classe,
// comea com letra maiscula.
String valor = abcd;
Concatenao
Utiliza-se o operador + para se concatenar strings.
Exemplo:
String nome = Silvio;
String sobrenome = Cesar;
String nomeCompleto = nome + sobrenome;
Quando se concatena um string com um valor que no um string o valor convertido
para string.
String valor = PG + 13; // valor = PG13
Este tipo de concatenao muito utilizada em comandos de sada de dados. Por
exemplo:
int resposta = 10;
System.out.println (A resposta + resposta);
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 18
Substrings
Para extrair um substring de um string maior deve-se utilizar o mtodo substring da
classe String. Por exemplo:
String nome = Luciana;
String outroNome = nome.substring (0, 5); // Extrai Lucia
O substring s.substring (a, b) possui sempre ba caracteres.
Editando Strings
Para descobrir o tamanho de um String:
String nome = Juliana da Rocha;
int n = nome.length(); // retorna 16
Assim como char representa caracteres Unicode, String representa seqncias de
caracteres Unicode. possvel recuperar um caracter especfico de um string.
Exemplo:
nome.charAt (n); // retorna o caracter na n-sima posio.
// A primeira posio a zero.
A classe String no fornece nenhum mtodo que nos permita alterar um caracter em um
string. Logo, para modificar um string preciso mudar o valor da varivel que o contm.
Exemplo:
String nome = Juliana da Rocha;
nome = nome.substring (0, 6) + o + nome.substring (7, 9);
// Resulta Juliano da Rocha
Se voc pretende escrever uma aplicao que, por exemplo, l do teclado caracteres a
medida que eles so digitados e os concatena a um string, ser mais eficiente utilizar a
classe StringBuffer, que ser examinada mais adiante.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 19
Comparando Strings
Para verificar se dois strings so iguais:
s.equals (t); // Retorna true se os strings s e t so iguais.
Juliana.equals (nome) // Note que constantes tb
// podem ser utilizadas.
No utilize == para verificar se dois strings so iguais. Isto apenas vai determinar se eles
se encontram armazenados no mesmo local de memria. Se strings esto armazenados no
mesmo local, so iguais, mas perfeitamente possvel armazenar strings iguais em locais
diferentes.
Se o compilador sempre armazenasse strings iguais no mesmo local seria possvel utilizar
o operador == para testar igualdade. No entanto, apenas strings constantes so
compartilhados. Strings resultantes de operaes como + ou substring no so
compartilhados, logo, nunca utilize == para comparar strings ou voc ter o pior tipo de
bug para resolver: o intermitente.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 20
Inteiros byte, short, int e long
Existem 4 tipos inteiros na linguagem Java. Cada tipo declarado utilizando-se uma das
seguintes palavras-chave: byte, short, int e long. Literais do tipo inteiro podem
ser representados utilizando-se uma das seguintes formas: decimal, octal ou hexadecimal.
2 O valor decimal 2.
077 O zero a esquerda indica que se trata de um valor octal.
0xBASE Os caracteres 0x esquerda indicam que se trata de um nmero
hexadecimal.
Observao: Todos os tipos inteiros em Java so nmeros com sinais.
Literais do tipo inteiro possuem o tipo int a menos que explicitamente seguido da letra
L. O L indica que se trata de um valor do tipo long. Note que em Java vlido
utilizar a letra L em maiscula ou minscula, no entanto, no uma boa opo utilizar a
letra L minscula pois pode ser confundida com o dgito 1 (um).
Verses long dos literais exibidos acima:
2L O valor decimal 2, como um long.
077L O zero a esquerda indica que se trata de um valor octal.
0xBASEL Os caracteres 0x esquerda indicam que se trata de um nmero
hexadecimal.
A seguir vem o tamanho e a faixa dos quatro tipos inteiros. (Independente de plataforma)
Comprimento Tipo Faixa
8 bits (1 byte) byte -2
7
. . . 2
7
1 -128 a 127
16 bits (2 bytes) short -2
15
. . . 2
15
1 - 32.768 a 32.767
32 bits (4 bytes) int -2
31
. . . 2
31
1 - 2.147.483.648 a 2.147.483.648
64 bits (8 bytes) long -2
63
. . . 2
63
1
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 21
Pontos Flutuantes float e double
Uma varivel ponto flutuante pode ser declarada utilizando-se as palavras-chave float
ou double.
Float
A razo para se utilizar float em vez de double no uma questo de desempenho,
embora operaes com variveis do tipo double sejam ligeiramente mais lentas do que
com variveis do tipo float, mas uma questo de consumo de memria, especialmente
quando se est trabalhando com uma grande quantidade de dados deste tipo e para manter
a compatibilidade com dados armazenados em arquivos externos.
Faixa de valores: -3.4E38 a 3.4E38
Veja os exemplos abaixo para compreender como representar literais vlidos do tipo
float:
1e1f 2.f .3f 3.14f 6.02e+23f
O sufixo F ou f sempre requerido em literais do tipo float. Um erro comum deixar de
fora o sufixo de um literal do tipo float, conforme vem abaixo:
float variavel = 6.5;
Error: cast explcito necessrio para converter um double em
float.
O correto seria:
float variavel = 6.5f;
Um literal double no pode ser designado a uma varivel float sem um cast mesmo que o
valor esteja na faixa dos valores permitidos para um float. A razo disto que alguma
preciso nos dgitos decimais pode ser perdida.
Literais ponto flutuante so do tipo double a menos que explicitamente declarados
como float.
Comprimento Tipo
32 bits float
64 bits double
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 22
Double
Variveis do tipo double referenciam nmeros ponto flutuante armazenados em 64 bits.
Faixa de valores: -1.7E308 a 1.7E308
Exemplos de literais vlidos do tipo double:
1e1 2. .3 3.14 6.02e+23d
Neste formato basta fornecer ao compilador um ponto decimal ou um expoente. O sufixo
D ou d ou sem sufixo, indica que se trata de um double. Na prtica se costuma omitir
o D.
O maior nmero do tipo double um pouco maior do que um 17 seguido de 307 zeros.
Observaes:
Em java a faixa dos nmeros inteiros no depende da mquina onde voc vai executar
o programa, isto , ao mudar um programa de uma plataforma para outra no
preciso mexer no programa. Naturalmente isto causa uma certa perda de desempenho,
mas este no o maior gargalo.
No caso de um overflow ou no caso de uma diviso por zero, ocorrero erros.
Aspas simples so utilizadas para representar constantes do tipo char. Por exemplo,
H um caracter. J H representa um string contendo um nico caracter.
Variveis
Exemplos de declarao de variveis:
byte b;
int umaVariavelInteira, outraVariavelInteira; // Ambas inteiras
long umaVariavelLong;
char ch;
O nome de uma varivel deve comear com uma letra e pode possuir os seguintes
caracteres: A-Z, a-z, 0-9, _ ou qualquer caracter unicode que represente uma
letra. Todo nome de varivel case sensitive.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 23
Designaes e Inicializaes
int valor; // Isto uma declarao
valor = 37; // Isto uma designao
char yesChar;
yesChar = Y;
int i = 10; // E isto uma declarao seguida de uma designao
Observao: Em java possvel declarar uma varivel em qualquer lugar do cdigo, mas
esta declarao s pode aparecer uma vez em qualquer bloco de um mtodo.
Converses entre Tipos Numricos
Se um dos operandos do tipo double, o outro ser convertido para double.
Seno, se um dos operandos do tipo float, o outro ser convertido para float.
Seno, se um dos operandos do tipo long, o outro ser convertido para long.
O mesmo ocorre com as variveis dos tipos inteiros: int, short e byte (nesta ordem).
Como converter um double em int:
double x = 9.997;
int nx = (int) x; // A varivel nx ir receber o valor 9
Como arredondar um nmero ponto flutuante para o valor inteiro mais prximo:
double x = 9.997
int nx = (int) Math.round(x); // nx receber 10
Observaes:
preciso utilizar (int) porque o resultado retornado pelo mtodo round do tipo
long e uma varivel do tipo long s pode ser atribuda a outra do tipo int
efetuando-se a converso explicitamente uma vez que existe a possibilidade de se
perder informao.
possvel efetuar converso atravs de uma simples designao se estas designaes
ocorrerem na ordem indicada a seguir: byte short int long float
double.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 24
Constantes
Em java utiliza-se a palavra-chave final para definir constantes. Por exemplo:
public class Constantes1
{ public static void main (String[] args)
{ final double CM_POR_POLEGADA = 2.54;
double larguraPapel = 8.5;
double alturaPapel = 11;
System.out.println ("Tamanho do papel em centmetros: "
+ larguraPapel * CM_POR_POLEGADA + " por "
+ alturaPapel * CM_POR_POLEGADA);
}
}
A palavra-chave final indica que possvel atribuir um valor a CM_POR_POLEGADA uma
nica vez. Qualquer tentativa de modific-la causa um erro de compilao.
Como definir uma constante de forma que ela possa ser utilizada por todos os mtodos de
uma classe:
public class Constantes2
{ private static final double G = 9.81; // fora da gravidade
public static void main (String[] args)
{ System.out.println (G + " metros por segundo ao quadrado");
}
}
Observaes:
Para se obter o efeito desejado a definio da constante aparece fora do mtodo main.
Se em vez de private tivssemos utilizado o access modifier public, outros
mtodos Java fora desta classe tambm poderiam acessar livremente esta constante.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 25
Variveis de Classe
Uma varivel static similar em alguns aspectos a uma varivel global em outras
linguagens. Java no possui variveis globais como outras linguagens, mas uma varivel
esttica uma varivel que pode ser acessada por qualquer instncia da classe.
Este tipo de varivel costuma ser chamada de varivel de classe (Class Variable) para
distingui-la de uma varivel de instncia (instance variable ou member variable).
Exemplo:
public class Contar
{ private int numeroDeSerie;
private static int contador = 0;
public Contar()
{ contador++;
numeroDeSerie = contador;
}
}
No exemplo acima, todo objeto da classe Contar criado com um numeroDeSerie
diferente. A varivel contador compartilhada por todas as instncias, logo quando o
construtor de um objeto a incrementa, est incrementando uma varivel global a todas as
instncias desta classe.
Se a varivel esttica for marcada como pblica, ela poder ser acessada por outras
classes.
public class StaticVar
{ public static int numero;
}
public class OtherClass
{ public void metodo()
{ int x = StaticVar.numero; // No necessrio
// instanciar a classe
}
}
Observaes:
Variveis globais a uma classe so inicializadas automaticamente, isto , possuem valores
default caso no sejam explicitamente inicializadas. Objetos so inicializados como null,
variveis boleanas recebem false, e variveis numricas recebem zero.
Cuidado! Variveis globais a uma classe podem ser sobrepostas por variveis com o
mesmo nome definidas dentro de um mtodo da classe. Isto , dentro do mtodo fica
valendo o valor da varivel local, e fora dele, o valor da varivel global.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 26
E finalmente, embora v contra tudo que a orientao a objetos prega, trocando-se a
palavra-chave private por public possvel definir uma verdadeira varivel global que
poder ser acessada por todos os mtodos de uma aplicao, isto , por mtodos de outras
classes. Logo, toda varivel global deve ser private.
Operadores
Operadores aritmticos: +, -, *, /
O operador / efetua diviso inteira se ambos os argumentos so inteiros.
Para se obter o resto da diviso de um nmero por outro utiliza-se o %. Por
exemplo: 15 % 2 1.
possvel efetuar operaes aritmticas na declarao e inicializao de uma
varivel. Por exemplo:
int n = 5;
int a= 2 * n; // a vale 10
Assim como em C e em C++:
x += 4;
equivalente a
x = x + 4;
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 27
Exponenciao
Java no possui um operador para exponenciao. Utilize o mtodo pow que faz parte da
classe Math de java.lang. Exemplo:
double y = Math.pow(x, a); // y = x
a
Ambos os argumentos deste mtodo so do tipo double, assim como o resultado
retornado.
Operadores de Incremento e Decremento
int n = 12;
n++; // equivale a: n = n + 1
int m = 7;
int n = 7;
int a = 2 * ++m; // agora a vale 16 e m vale 8
int b = 2 * n++; // agora b vale 14 e n vale 8
Como estes operadores (++ e --) modificam o valor de uma varivel, no podem ser
aplicados a nmeros. Por exemplo, 4++ no um comando vlido. No recomendvel
utilizar o operador ++ dentro de outras expresses. Costumam causar bugs difceis de
resolver.
Operadores Relacionais e Boleanos
Para testar se 3 igual a 7:
(3 == 7)
Para testar se 3 diferente de 7:
(3 != 7)
Existem ainda: <, <=, > e >=
Assim como em C++, java utiliza && para and e || para or.
No exemplo abaixo, se o valor da expresso A falso, a expresso B no calculada:
(A && B)
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 28
Parnteses e a Hierarquia dos Operadores
Se parnteses no so utilizados, as operaes so realizadas na ordem indicada abaixo:
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 29
ENTRADA DE DADOS E FORMATAO DA SADA
Lendo Dados
Ler dados do teclado bastante difcil em java. Naturalmente isto no um problema se
voc pretende escrever programas grficos que coletam dados dos usurios a partir de
caixas de texto. Mas um problema para quem pretende escrever programas simples com
o objetivo de aprender a linguagem.
Para facilitar a entrada de dados vamos utilizar uma classe denominada Console que
possui mtodos para este fim.
Exemplo de leitura de um double:
import corejava.*; // importa o corejava package
public class ConsoleDouble
{ public static void main (String[] args)
{ double x = Console.readDouble
("Digite um numero. Vou somar 2 a ele.");
System.out.println (x + 2);
}
}
Exemplo de leitura de um String:
import corejava.*; // importa o corejava package
public class ConsoleString
{ public static void main (String[] args)
{ String nome;
nome = Console.readLine ("Digite seu nome: ");
System.out.println ("Oi " + nome);
}
}
O mtodo readLine exibe uma mensagem e captura o string digitado pelo usurio aps
ser apertada a tecla <Enter>. H ainda um terceiro mtodo: readInt que pode ser utilizado
da mesma forma como o readDouble. Caso o usurio tecle <Enter> sem digitar um
nmero, a mensagem que solicita a digitao de um nmero ser novamente exibida.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 30
Formatando a Sada
Sada sem formatao:
x = 10000.0 / 3.0
System.out.print (x);
Imprime
3333.3333333333335
Para formatar a sada utilize a classe NumberFormat definida no pacote java.text. Esta
classe possui trs mtodos para a formatao de:
Nmeros
Valores monetrios
Percentuais
Suponha que o seu default locale que depende da configurao da mquina seja
Brasil. (Um locale um conjunto de especificaes, de um determinado pas, aplicadas a
propriedades de strings e nmeros, tais como ordem dos caracteres, smbolo monetrio,
separador decimal, etc.)
Para obter um formatador para o default locale, utilize os trs mtodos:
NumberFormat.getNumberInstance()
NumberFormat.getCurrencyInstance()
NumberFormat.getPercentInstance()
Cada um destes mtodos retorna um objeto do tipo NumberFormat. Voc pode utilizar
este objeto para formatar um ou mais nmeros.
Exemplo:
import java.text.*;
public class FormataNumero1
{ public static void main (String[] args)
{ double x = 10000.0 / 3.0;
NumberFormat nf = NumberFormat.getNumberInstance();
String fx = nf.format (x);
System.out.println (fx);
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 31
Tambm possvel determinar o nmero mnimo e mximo de dgitos inteiros e
fracionrios que devem ser exibidos. Para fazer isto devemos utilizar os mtodos da
classe NumberFormat, listados abaixo:
setMinimumIntegerDigits
setMinimumFractionDigits
setMaximumIntegerDigits
setMaximumFractionDigits
Exemplo:
import java.text.*;
public class FormataNumero2
{ public static void main (String[] args)
{ double x = 10000.0 / 3.0;
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMaximumFractionDigits (2);
nf.setMinimumFractionDigits (2);
// nf.setMaximumIntegerDigits (5);
// Cuidado, isto pode truncar o resultado.
nf.setMinimumIntegerDigits (1);
String fx = nf.format (x);
System.out.println (fx);
}
}
possvel formatar nmeros de forma apropriada para diversos pases. No caso da
Alemanha, por exemplo, deveramos utilizar um objeto predefinido do tipo Locale -
denominado Locale.GERMAN que conhece as regras Alems de formatao de nmeros.
Exemplo:
double x = 10000.0 / 3.0;
NumberFormat cf =
NumberFormat.getCurrencyInstance (Locale.GERMAN);
System.out.println (cf.format (x));
Este cdigo deveria imprimir:
3.333,333 DM
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 32
possvel ainda criar seu prprio formato. Por exemplo, voc pode querer exibir um
nmero com seis dgitos aps o ponto decimal, mas sem separador de milhar.
Exemplo:
DecimalFormat df = new DecimalFormat (0.######);
System.out.println (df.format(x));
Este cdigo deveria imprimir:
3333,333333
Observao: Quando utilizamos mtodos para a formatao de nmeros o default Locale
utilizado.
Voc pode utilizar os caracteres da tabela abaixo para formatar Strings:
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 33
PRINCIPAIS ESTRUTURAS DE PROGRAMAO EM JAVA
Controle de Fluxo
Antes de comearmos com comandos de controle de fluxo preciso conhecer mais sobre
blocos. Um bloco formado por um conjunto de comandos Java entre chaves. Blocos
definem o escopo de suas variveis e podem ser aninhados.
Exemplo:
public static void main (String[] args)
{ int n;
...
{ int k; // Varivel local a este bloco.
int n: // Erro! No permitida a redefinio de n em
// um bloco mais interno.
...
}
}
Comandos Condicionais
Exemplo 1:
if (nome.equals("Silvio"))
bonus = 100;
Exemplo 2:
if (nome.equals("Silvio"))
{ desempenho = "satisfatrio";
bonus = 100;
}
Exemplo 3:
if (numero == 10)
{ valor = valor + 100;
bonus = 500;
}
else
{ valor = valor + 200;
bonus = 1200;
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 34
Exemplo 4:
if (numero == 10)
{ valor = valor + 100;
bonus = 500;
}
else if (numero == 20)
{ valor = valor + 300;
bonus = 1200;
}
else if (numero == 30)
{ valor = valor + 700;
bonus = 1900;
}
else
{ valor = valor + 1100;
bonus = 3000;
}
Exemplo 5:
if (x != 0 && 1 / x > 0) // No divide por zero.
x = x + 1;
Exemplo 6:
public class ManipulaStrings
{ public static void main (String[] args)
{ String r = "bcd";
String s = "abcd".substring(1,3) + "abcd".substring(3,4);
System.out.println("r = " + r);
System.out.println("s = " + s);
if (r == s)
System.out.println
("'r' e 's' ocupam a mesma posio de memria");
else
System.out.println
("'r' e 's' ocupam posies de memria diferentes");
}
}
Working Directory - C:\Java\Packages\Introd\Exemplo11b\
r = bcd
s = bcd
'r' e 's' ocupam posies de memria diferentes
Process Exit...
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 35
Loops Indeterminados
Utilizados quando no se sabe quantas vezes o loop deve ser executado.
Exemplo 1: Calcula a soma dos nmeros de 1 a limite.
import corejava.*;
public class SomaNumeros
{ public static void main (String[] args)
{ int soma = 0;
int i = 1;
int limite = Console.readInt ("Digite um numero maior " +
"do que zero: ");
while (i <= limite)
{ soma = soma + i;
i++;
}
System.out.println ("A soma dos numeros de 1 a " + limite +
" e' " + soma);
}
}
Exemplo 2: Calcula o fatorial de um nmero.
import corejava.*;
public class Fatorial
{ public static void main (String[] args)
{ int numero = Console.readInt ("Digite um numero maior " +
"do que zero: ");
if (numero == 0)
System.out.println ("O fatorial de 0 1");
else
{ int num = numero;
int fat = 1;
do
{ fat = fat * numero;
numero--;
}
while (numero != 1);
System.out.println ("O fatorial de " + num + " e' " +
fat);
}
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 36
Loops Determinados
Exemplo 1: Calcula o fatorial de um nmero.
import corejava.*;
public class Fatorial2
{ public static void main (String[] args)
{ int numero = Console.readInt ("Digite um numero maior " +
"do que zero: ");
if (numero == 0)
System.out.println ("O fatorial de 0 1");
else
{ int fat = 1;
for (int i = 1; i <= numero; i++)
fat = fat * i;
System.out.println ("O fatorial de " + numero +
" e' " + fat);
}
}
}
Observao: No comando for (valor inicial; valor limite; incremento) permitido mudar
os valores de limite e incremento a cada novo iterao. Para o clculo do valor inicial, do
limite e do incremento permitida a utilizao de expresses aritmticas.
Exemplo 2: Um loop sem fim devido a erros de arredondamento. Cuidado ao testar
igualdade com nmeros ponto flutuante.
import corejava.*;
public class ForClass
{ public static void main (String[] args)
{ for (double i = 0; i != 10.0; i += 0.01)
System.out.println (i);
System.out.println ("Fora do for");
}
}
Observao: for (double i=0; i=10.0; i+=0.01) provoca erro uma vez que a
segunda condio significa: enquanto i igual a 10 faa.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 37
O Comando Switch
Exemplo:
import corejava.*;
public class SwitchCmd
{ public static void main (String[] args)
{ int opcao = Console.readInt ("Selecione uma opo (de 1 a 4)");
switch (opcao)
{ case 1:
System.out.println ("Voc digitou o nmero um");
// break; Sem este break, o prximo System.out ser
// executado.
case 2:
System.out.println ("Voc digitou o nmero dois");
break;
case 3:
System.out.println ("Voc digitou o nmero tres");
break;
case 4:
System.out.println ("Voc digitou o nmero quatro");
break;
default:
System.out.println ("Opo invlida");
break; // Este break desnecessrio.
}
System.out.println ("Fora do Switch");
}
}
A varivel utilizada no switch deve ser do tipo int, short ou do tipo char. No
possvel selecionar uma opo por faixa de valores.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 38
O Comando Break
Exemplo 1: Sem a utilizao de um label.
import corejava.*;
public class Break1
{ public static void main (String[] args)
{ for (double i = 0; i != 10; i += 0.01)
{ if (i > 10) break; // Evita que este loop no tenha fim
System.out.println (i);
}
System.out.println ( "Fora do For");
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 39
Exemplo 2: Com a utilizao de um label.
Em algumas situaes pouco comuns preciso fazer com que o fluxo da execuo saia de
um loop aninhado profundo. Nestes casos, em vez de programar condies extras nos
vrios loops aninhados, pode-se utilizar o comando break - com um label - para onde o
fluxo da execuo deve ser desviado.
import corejava.*;
public class BreakLabel
{ public static void main (String[] args)
{ int n;
read_data:
{ while ( . . . )
{ . . .
for ( . . . )
{ n = Console.readInt ( . . . );
if ( n < 0 ) // No deveria acontecer. No pode
// continuar.
Break read_data:
/* O fluxo da execuo desviado para o label e o
prximo comando a ser executado ser o primeiro aps o bloco read_data,
onde dever ser testado em que condies a execuo chegou l. */
. . .
}
}
}
// Testando como a execuo chegou aqui.
if ( n < 0 )
// Situao que no deveria ter ocorrido
. . .
else
{ // Chegou aqui normalmente
. . .
}
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 40
Mtodos de Classes (Funes Definidas pelo Usurio)
A definio de um mtodo deve ocorrer dentro de uma classe. Ela pode ocorrer em
qualquer lugar dentro da classe, embora seja comum colocar-se os mtodos antes do
mtodo main. Existem muitos tipos de mtodos em java. No momento, vamos utilizar
apenas mtodos public e static, assim como o mtodo main.
Java no possui mtodos globais. Todos os mtodos devem ser definidas dentro de uma
classe. Os mtodos que vamos estudar a seguir ainda no operam sobre objetos e so, por
esta razo, definidos como static.
A seguir vem a descrio de um mtodo que nos indica qual a chance que temos de
acertar numa loteria com n nmeros retirados de um total de k nmeros. Por exemplo,
para acertarmos na sena preciso acertar 6 nmeros em 50, logo a chance que temos de
ganhar : (50 * 49 * 48 * 47 * 46 * 45) / (1 * 2 * 3 * 4 * 5 * 6), isto , 1 chance em
15.890.700.
E qual seria a nossa chance se tivssemos que acertar 7 nmeros em 38?
public static long calculaChanceLoteria (int maiorNumero,
int numero)
{ long r = 1;
long j = 1;
int i;
for (i = 1; i <= numero; i++)
{ r = r * maiorNumero;
maiorNumero--;
j = j * i;
}
return r/j;
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 41
Observaes:
Como um mtodo esttico pode ser chamado sem qualquer instncia da classe qual
pertence, no cabe fazer referncia a this. A conseqncia disto que um mtodo
esttico no pode acessar variveis alm dos seus argumentos e variveis estticas. A
tentativa de acessar variveis no estticas provocar um erro de compilao.
Exemplo:
public class Erro
{ int x;
public static void main (String args[])
{ x = 9; // Erro de compilao
}
}
Variveis declaradas dentro de um mtodo so locais a ele. No podem se acessadas
nem modificadas por nenhuma outra varivel com mesmo nome na classe. Quando
java chama um mtodo, todas as variveis locais so inicializadas como indicado no
corpo do mtodo. Dentro de um mtodo o escopo de uma varivel local
determinado pelo bloco no qual ela foi declarada. Note que voc deve inicializar
todas as variveis. Variveis locais em um mtodo no recebem valores default. J as
variveis de instncia so criadas quando o objeto construdo e continua a existir
enquanto o objeto necessrio.
Quando java executa um comando return retornado para o mtodo chamador o valor
constante da expresso que segue este comando. Caso voc no deseje retornar
nenhum valor, indique este fato no header atravs da palavra-chave void.
Ao sair de um mtodo a memria alocada a variveis locais automaticamente
reclamada. (garbage colection)
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 42
A seguir apresentamos o mtodo main com a chamada ao mtodo calculaChanceLoteria.
import corejava.*;
public class CalculaChanceLoteria
{ public static long calculaChanceLoteria (int maiorNumero,
int numero)
{ long r = 1;
long j = 1;
int i;
for (i = 1; i <= numero; i++)
{ r = r * maiorNumero;
maiorNumero--;
j = j * i;
}
return r/j;
}
public static void main (String[] args)
{ int numero = Console.readInt ("Quantos nmeros voc " +
"quer apostar? ");
int maiorNumero = Console.readInt ("Qual o maior nmero? ");
long suaChance = calculaChanceLoteria (maiorNumero, numero);
System.out.println ("Quantidade de nmeros = " + numero);
System.out.println ("Maior nmero = " + maiorNumero);
System.out.println ("Sua chance de acertar de 1 em " +
suaChance);
}
}
Observaes:
Na chamada ao mtodo calculaChanceLoteria no preciso especificar o nome da
classe uma vez que tanto o mtodo main quanto o mtodo calculaChanceLoteria
pertencem mesma classe CalculaChanceLoteria.
Note que nas chamadas ao mtodo getNumberInstance() nos exemplos apresentados
anteriormente, sempre especificamos o nome da classe (NumberFormat) uma vez que
este mtodo pertence a outra classe.
NumberFormat.getNumberInstance();
Quando o comando long suaChance = calculaChanceLoteria
(maiorNumero, numero) executado, os valores correntes das variveis
maiorNumero e numero so passados para o mtodo
calculaChanceLoteria. importante saber que em java todos os argumentos
passados para mtodos so passados por valor e no por referncia. Logo, no
possvel mudar o valor de variveis atravs de chamadas a mtodos.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 43
Recursividade
Tipos de recursividade:
Recursividade direta: quando um sub-programa chama apenas a si prprio.
Recursividade indireta: quando um mtodo chama outro que, por sua vez, chama o
primeiro.
Ambos os tipos de recursividade so possveis em java. A seguir ser apresentado o
algoritmo recursivo para se calcular a nossa chance de ganhar em uma loteria em que so
sorteados k nmeros de um total m nmeros.
public static long calculaChanceLoteria (int maiorNumero, int numero)
{ if (numero <= 0) return 0; // No deveria ocorrer.
else if (numero == 1) return maiorNumero;
else return maiorNumero *
calculaChanceLoteria (maiorNumero - 1, numero - 1) / numero;
}
Observao: Deve-se evitar solues recursivas quando existe uma soluo no recursiva
bvia.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 44
ARRAYS
Em Java arrays so objetos de primeira classe. Um objeto de primeira classe um tipo
objeto definido pela linguagem e no pelo usurio. Como so objetos, possvel, por
exemplo, atribuir um array de inteiros a outro, assim como voc faz com uma varivel
inteira. Se voc atribuir um array de inteiros a outro, ambos os arrays iro referenciar o
mesmo conjunto de dados, isto , a modificao efetuada em um deles afetar o outro.
Uma vez criado um array no se pode facilmente trocar o seu tamanho. Se voc
necessitar aumentar o tamanho de um array ao longo da execuo de um programa ser
necessrio utilizar um objeto diferente, denominado vector. Mais adiante estudaremos
os vectors.
Voc j viu alguns exemplos de arrays em java: o argumento String[] args do
mtodo main indica que este mtodo recebe um array de strings.
Arrays so o primeiro exemplo de objetos, cuja criao um programa deve manipular
explicitamente. Por exemplo:
int[] arrayDeInteiros;
arrayDeInteiros = new int[100];
O primeiro comando, a declarao, aloca espao suficiente para armazenar a referncia.
O segundo comando aloca o espao necessrio para se armazenar 100 nmeros inteiros.
Esta regio de memria alocada atravs do comando new int[100] dita um objeto.
A varivel arrayDeInteiros recebe uma referncia (um ponteiro) para este objeto,
isto , para a regio de memria onde os nmeros inteiros podero ser armazenados.
O comando abaixo cria um array que poder conter 100 nmeros inteiros. As entradas
neste array so numeradas de 0 a 99. Uma vez criado o array podemos atribuir valores a
ele, por exemplo, com um loop:
int[] arrayDeInteiros = new int[100];
for (int i = 0; i < 100; i++)
arrayDeInteiros [i] = i; // Preenche o array com os nmeros 0
// a 99.
Em Java h uma forma abreviada de se criar um objeto array e inicializ-lo ao mesmo
tempo. Exemplo:
int[] algunsPrimos = {2, 3, 5, 7, 11, 13);
Note que no foi preciso chamar o new com esta sintaxe.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 45
Pode-se inclusive inicializar um array annimo com esta sintaxe:
new int[] {2, 3, 5, 7, 11, 13};
O nmero de elementos do array contado e o tamanho do array especificado com este
valor. Esta sintaxe pode ser utilizada quando se deseja passar um array para um mtodo e
no se deseja criar uma varivel local para este fim. Exemplo:
printLabels (new String[] {"Compras", "Vendas"};
A forma acima uma abreviao de:
String[] departamentos = {"Compras", "Vendas"};
printLabels (departamentos);
Para se descobrir o nmero de elementos de um array utilize o mtodo length,
conforme vem a seguir:
for (int i = 0; i < departamentos.lenght; i++)
System.out.println (departamentos [i]);
Copiando Arrays
possvel copiar um array para outro, mas neste caso, ambos os arrays faro referncia
aos mesmos dados.
int[] primeirosPrimos = {2, 3, 5, 7, 11, 13};
int[] maisPrimos = primeirosPrimos;
maisPrimos [5] = 12; // Agora primeirosPrimos [5] tambm vale 12.
Se voc realmente deseja copiar os valores de um array para outro, utilize o mtodo
arraycopy definido na classe System.
System.arraycopy (from, fromIndex, to, toIndex, count);
Exemplo:
public class CopiaArray
{ public static void main (String args[])
{ int[] primeirosPrimos = {2, 3, 5, 7, 11, 13};
int [] outrosNumeros =
{1001, 1002, 1003, 1004, 1005, 1006, 1007};
System.arraycopy (primeirosPrimos, 2, outrosNumeros, 3, 4);
for (int i = 0; i < outrosNumeros.length; i++)
{ System.out.println
("Posio "+ i + " aps a cpia = " +
outrosNumeros [i]);
}
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 46
Sada:
Posio 0 aps a cpia = 1001
Posio 1 aps a cpia = 1002
Posio 2 aps a cpia = 1003
Posio 3 aps a cpia = 5
Posio 4 aps a cpia = 7
Posio 5 aps a cpia = 11
Posio 6 aps a cpia = 13
Process Exit...
Arrays como Argumentos
Como arrays em java so, na verdade, objetos, um mtodo pode alterar um elemento em
um array. Lembre-se que a passagem de parmetros em java por valor o que faz com
que um mtodo no possa alterar o valor de uma varivel comum.
Exemplo:
public class OrdenaArray
{ public static void sort(int[] a)
{ int n = a.length;
boolean troca = true;
while (troca)
{ troca = false;
for (int i = 0; i < n - 1; i++)
{ int temp = a[i];
if (a[i] > a[i+1])
{ a[i] = a[i + 1];
a[i + 1] = temp;
troca = true;
}
}
}
}
public static void print (int[] a)
{ for (int i = 0; i < a.length; i++)
System.out.print (a[i] + " ");
System.out.println();
}
public static void main (String[] args)
{ // Cria um array com 10 nmeros inteiros
int [] a = new int [10];
int i;
// Preenche o array com nmeros gerados randomicamente
for (i = 0; i < a.length; i++)
a [i] = (int) (Math.random() * 100);
print (a);
sort (a);
print (a);
}
}
O Mtodo Lenght
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 47
Observe que o mtodo lenght retorna um nmero que representa a quantidade de posies
alocadas para o vetor.
public class ImprimeArray
{ public static void print (int[] a)
{ for (int i = 0; i < a.length; i++)
System.out.print (a[i] + " ");
System.out.println();
}
public static void main (String[] args)
{ // Cria um array com 10 nmeros inteiros
int [] a = new int [10];
int i;
// Preenche o array com nmeros gerados randomicamente
a [0] = (int) (Math.random() * 100);
a [1] = (int) (Math.random() * 100);
a [2] = (int) (Math.random() * 100);
a [3] = (int) (Math.random() * 100);
print (a);
}
}
Sada:
93 18 35 73 0 0 0 0 0 0
Process Exit...
Observaes:
Como o algoritmo de ordenao apresentado acima no muito eficiente ( apenas
fcil de programar), se voc desejar ordenar um grande array de nmeros, utilize um
dos mtodos de sort da classe Arrays.
int [] a = new int[10000];
. . .
Arrays.sort(a);
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 48
Retornando um Array
O tipo retornado por um mtodo tambm pode ser um array. Isto til quando um
mtodo gera uma seqncia de valores. Por exemplo, vamos escrever um mtodo que
gere uma seqncia de nmeros que possam ser utilizados em uma aposta na sena.
import java.util.*;
import corejava.*;
public class Loteria
{ public static int[] geraNumeros (int maiorNumero, int qtdNumeros)
{ int i;
int numeros[] = new int[maiorNumero];
int resultado[] = new int[qtdNumeros];
// Preenche um array com os nmeros 1, 2, 3, ..., maiorNumero.
for (i = 0; i < maiorNumero; i++) numeros [i] = i + 1;
for (i = 0; i < qtdNumeros; i++)
{ int j = (int) (Math.random() * (maiorNumero - i));
resultado [i] = numeros [j];
numeros [j] = numeros [maiorNumero - 1 - i];
}
return resultado;
}
public static void main (String[] args)
{ int qtdNumeros = Console.readInt ("Quantos numeros voce " +
"deseja apostar?");
int maiorNumero = Console.readInt ("Qual e' o maior numero?");
int [] a = geraNumeros (maiorNumero, qtdNumeros);
Arrays.sort (a);
System.out.println ("Quer ficar rico? Aposte a seguinte " +
"combinacao: ");
for (int i = 0; i < a.length; i++)
System.out.println (a [i]);
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 49
Arrays Multidimensionais
Como declarar uma matriz:
double [] [] umaMatriz;
S se pode utilizar um objeto (um array, neste caso) aps inicializ-lo com uma chamada
a new.
umaMatriz = new double [5] [6];
Uma vez inicializado, possvel acessar elementos individuais.
umaMatriz [i] [j] = 15;
Na realidade java no possui arrays multidimensionais, mas apenas arrays de arrays. No
exemplo anterior o array umaMatriz , na realidade, um array que contm cinco
elementos, e cada um deles um array de 6 nmeros ponto flutuantes, conforme vem na
figura abaixo.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 50
A expresso umaMatriz [i] referencia o i-simo subarray, isto , a i-sima linha da tabela.
J umaMatriz [i] [j] referencia a j-sima posio daquele array. Como as linhas de um
array so acessadas individualmente possvel troc-las:
double [] temp = umaMatriz [i];
umaMatriz [i] = umaMatriz [i + 1];
umaMatriz [i + 1] = temp;
Outra conseqncia do fato de que uma matriz um array de arrays que voc pode
utilizar a notao abreviada para inicializ-la, conforme vem a seguir:
int [] [] vendasDosUltimosDoisAnos = { {1997, 1998},
{100000, 200000} };
Tambm possvel definir ragged arrays (array dentado), isto , um array no qual
linhas diferentes possuem diferentes comprimentos. Abaixo vem um exemplo padro.
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
Como j nunca pode ser maior do que i, a matriz triangular. A i-sima linha possui i + 1
elementos. Para construir este array, primeiramente alocamos o array que armazena as
linhas.
int [] [] matrizDentada = new int [n + 1] [];
A seguir alocamos as linhas:
for (i = 0; i <= n; i++)
matrizDentada [i] = new int [i + 1];
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 51
Agora que o array j se encontra alocado, podemos acessar os elementos normalmente,
tomando o cuidado de no ultrapassar os limites.
import corejava.*;
public class CriaMatrizDentada
{ public static void main (String args[])
{ int i, j;
int n = Console.readInt ("Digite o numero de linhas da " +
"matriz:");
// Aloca matriz dentada
int [][] matrizDentada = new int [n][];
for (i = 0; i < n; i++)
matrizDentada [i] = new int [i + 1];
// Cria matriz dentada
for (i = 0; i < n; i++)
{ matrizDentada [i][0] = 1;
matrizDentada [i][i] = 1;
}
for (i = 2; i < n; i++)
for (j = 1; j < matrizDentada[i].length - 1; j++)
matrizDentada [i][j] = matrizDentada [i-1][j-1] +
matrizDentada [i-1][j];
// Imprime matriz dentada
for (i = 0; i < n; i++)
{ for (j = 0; j < matrizDentada[i].length; j++)
System.out.print (matrizDentada [i] [j] + " ");
System.out.println ("");
}
}
}
Determinando o nmero de linhas e de colunas
import corejava.*;
public class Principal
{ public static void main(String[] args)
{ int md[][] = new int [10][5];
System.out.println (md.length + " " + md[0].length);
// md.length retorna o nmero de linhas alocadas 10
// md[0].length retorna o nmero de colunas alocadas 5
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 52
OBJETOS E CLASSES
A programao estruturada tradicional consiste em projetar uma srie de funes para
resolver um problema. O prximo passo encontrar formas apropriadas de armazenar os
dados. Esta a razo pela qual o projetista da linguagem Pascal original, Niklaus Wirth,
chamou seu famoso livro de programao de Algorithms + Data Structures = Programs
(Prentice Hall, 1995). Note que neste ttulo Algorithms vm em primeiro lugar e
estruturas de dados em segundo. Isto mostra como os programadores pensavam naquela
poca. Primeiro voc decide como manipular os dados, e depois decide qual estrutura de
dados deve ser utilizada de forma que a manipulao seja mais fcil. OOP inverte esta
ordem: pe as estruturas de dados em primeiro lugar, para s ento verificar quais
algoritmos devem operar sobre estas estruturas.
O segredo de como ser produtivo com a OOP fazer com que cada objeto seja
responsvel pelas tarefas a ele relacionadas. Se um objeto precisa executar uma tarefa que
no da sua responsabilidade, preciso que ele tenha acesso ao objeto responsvel pela
tarefa. O primeiro objeto, ento solicita ao segundo para executar a tarefa. No jargo da
OOP objetos clientes enviam mensagens para objetos servidores.
Em particular, um objeto nunca deve manipular diretamente os dados internos de outro
objeto. Todas as comunicaes devem ser atravs de mensagens, isto , atravs de
chamadas a mtodos. Projetando os seus objetos para manipular seus dados internos,
maximiza-se a reusabilidade, reduz-se a dependncia entre os dados e reduz-se o tempo
de debug.
Assim como no desenvolvimento de mdulos em uma linguagem procedural, voc no
ir querer que um nico objeto faa muitas coisas. Tanto o projeto, quanto a programao
(debug) so simplificados quando pequenos objetos so construdos, em vez de objetos
gigantescos com complexas estruturas de dados e com centenas de mtodos para
manipular os dados.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 53
Terminologia
Tipos de Dados Agregados
Representa um modelo de alguma coisa em um programa. O modelo construdo
acrescentando a ele variveis que descrevem os vrios aspectos que especificam o estado
da entidade. Uma vez definido, variveis podem ser criadas utilizando o nome do tipo.
Algumas linguagens utilizam os termos Record ou tipos estruturados. Java
utiliza o termo Class.
Class
Uma verso de um tipo de dado agregado para uma linguagem orientada a objetos.
Estritamente falando, a idia de classe um superconjunto da idia de tipo agregado de
dado, mas as muitas caractersticas que diferenciam uma classe de um tipo agregado de
dados ainda no foram discutidas.
Uma classe geralmente descrita como um modelo a partir do qual os objetos so
instanciados. Uma classe funciona como uma forma de doces na culinria. Os objetos so
os prprios doces. Assim como para montar um doce voc necessita de massa, para
alocar um objeto voc necessita de memria. Java esconde muito bem de voc a
preparao desta massa (ou a alocao da memria). Voc simplesmente utiliza a
palavra-chave new para obter a massa (ou memria), e o coletor de lixo automtico
comer os doces (ou liberar a memria) quando ningum mais estiver interessado neles.
Object
Uma instncia de uma classe. A classe pode ser considerada um modelo. Um objeto o
que voc obtm cada vez que voc cria uma instncia da classe.
O comportamento de um objeto definido pelas mensagens que ele aceita. Um objeto
armazena a informao de como ele se parece no momento. Isto o que geralmente se
chama de estado do objeto. Um objeto pode mudar de estado ao longo do tempo, mas no
espontaneamente. Uma mudana no estado de um objeto deve ser conseqncia de
mensagens enviadas a ele (caso contrrio o encapsulamento estar quebrado).
O estado de um objeto, no entanto, no o descreve completamente, uma vez que cada
objeto possui uma identidade distinta. Por exemplo, em um sistema de processamento de
pedidos, dois pedidos so distintos mesmo que requisitem itens idnticos. O estado de um
objeto pode influenciar o seu comportamento. Se um pedido j foi enviado ou j foi
pago dever rejeitar uma mensagem que solicite a adio ou a remoo de itens. Por
outro lado, se um pedido encontra-se vazio, isto , nenhum item ainda foi pedido, ele
no deveria permitir que fosse enviado.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 54
Member
Um membro um dos elementos que formam um objeto. O termo tambm utilizado
para os elementos que definem uma classe. Os termos varivel membro, varivel de
instncia ou campo tambm so utilizados, significando a mesma coisa.
Reference
Uma varivel que possui um tipo classe. Atravs da varivel pode-se acessar um objeto
em particular. Este tipo de varivel denominada referncia.
Como Definir uma Classe
Para definir uma classe utilizamos objetos. Por exemplo, embora a linguagem Java
possua mais de uma classe para representar datas, suponha que desejamos criar um novo
tipo de dado para este fim. Poderamos, por exemplo, criar a classe Data, composta de
dia, ms e ano, assim:
public class Data
{ public int dia;
public int mes;
public int ano;
}
A palavra class deve ser escrita com letras minsculas e o nome da classe Date, por
conveno, deve ser escrito com a primeira letra maiscula.
Agora uma varivel pode ser declarada como sendo do tipo Data, e dia, ms e ano
podero ser acessados assim, caso tenham sido declaradas como public.
Date umaData; // Data do fim do mundo.
umaData.dia = 11;
umaData.mes = 08;
umaData.dia = 99;
Quando declaramos variveis de qualquer tipo primitivo (boolean, byte, short, char, int,
long, float e double), o espao de memria para a varivel alocado como parte da
operao. A declarao de uma varivel utilizando um tipo classe como String ou Array
ou qualquer tipo definido pelo usurio no aloca espao de memria.
Na realidade, a varivel que declarada com o tipo classe no contm o dado em si, mas
uma referncia para o dado. Voc pode pensar nesta referncia como um ponteiro para a
regio de memria onde o dado se encontra.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 55
Por exemplo:
No corpo de um mtodo a declarao:
Date hoje; // Declarando uma varivel com o tipo Date uma
// classe da linguagem Java para a criao de objetos
// que possam armazenar datas.
hoje = new Date();
Aloca o espao de memria necessrio para armazenar apenas a referncia:
hoje (inicialmente com null)
A construo do objeto aloca e inicializa a rea de um objeto do tipo Date:
Date hoje;
hoje = new Date();
hoje (inicialmente com null indica que a referncia
no est apontando para nada)
day
month
year
E finalmente, a operao de atribuio faz com que faz com que a varivel hoje recebe
uma referncia para um objeto do tipo Date.
Date hoje;
hoje = new Date();
hoje
day
month
year
????
????
0
0
0
0x01abcd
0
0
0
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 56
O fato de Java tratar variveis que so declaradas como do tipo classe como referncias,
trs conseqncias relativas ao significado das designaes:
int x = 7;
int y = x;
String s = Oi
String t = s;
x
y
s
t
Programadores C / C++ devem tomar cuidado. O identificador null em Java grafado
com letras minsculas e no em maisculas como nestas linguagens.
Uma classe, alm das variveis de instncia, possuem mtodos que permitem o acesso a
estas variveis. Algumas linguagens de programao, incluindo Java, permitem uma forte
associao entre a declarao de um tipo de dado e a declarao do cdigo que se
pretende utilizar para manipular as variveis deste tipo.
Em Java, voc pode criar uma associao entre o tipo Data e a operao amanha,
assim:
public class Data
{ public void amanha()
{ // cdigo para incrementar um dia
}
private int dia, mes, ano;
}
Em Java voc pode referenciar a parte do cdigo denominada amanha como um
mtodo, no entanto voc tambm ir escutar os termos funo membro e funo.
Em linguagens que no suportam esta associao entre dados e cdigo, a declarao do
mtodo amanha especifica uma data em particular que deve ser incrementada em um
dia. Por exemplo:
void amanha(Data d);
0x01234567
0x01234567
Oi
7
7
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 57
A combinao de tipo de dado com seus operadores chamada de tipo abstrato de dados.
Linguagens como Java que suportam tipo abstrato de dados criam uma forte associao
entre dado e cdigo. Requisitamos que determinado mtodo atue sobre um objeto assim:
Data d = new Data(); // criado um objeto do tipo data
// (denominado d) contendo a data de hoje.
d.amanha(); // Esta notao reflete a idia de que o
// comportamento determinado pelo tipo
// do dado.
Em Java mtodos so definidos utilizando uma abordagem que muito similar
abordagem utilizada em outras linguagens como C e C++. A declarao dos mtodos
possui a seguinte forma:
<modificadores> <tipo do dado retornado> <nome do mtodo> (<lista de argumentos>)
<bloco>
Por exemplo:
public void adicionaDias(int dias)
instrui o corpo do mtodo adicionaDias para receber um argumento que indica o nmero
de dias que deve ser somado a uma data.
Exemplo de chamada a este mtodo:
Data d = new Data(); // O operador new utilizado para se
// criar uma instncia da classe Data
d.adicionaDias(10);
No exemplo acima so somados 10 dias data de hoje.
Os modificadores so:
public static
private final
protected
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 58
Utilizando a palavra-chave private na declarao dos campos dia, ms e ano da classe
Data possui o efeito de tornar impossvel o acesso a estes campos a partir de qualquer
cdigo, exceto atravs dos mtodos da prpria classe Data.
public class Data
{ public void amanha()
{ // cdigo para incrementar um dia
}
private int dia, mes, ano;
}
Logo, considerando a definio da classe Data acima, o seguinte cdigo ilegal:
public class Principal
{ public static void main(String args[])
{ Data umaData = new Data();
umaData.dia = 21; // Cdigo ilegal
}
}
Impedir que uma classe acesse diretamente os dados de outra como em (umaData.dia
= 21;) trs grandes vantagens para a qualidade de um programa. Como itens de dados
individuais de uma classe (campos, variveis de instncia) so inacessveis, a nica forma
de l-los e modific-los atravs de mtodos. Logo, se um programa requer consistncia
interna dos membros de uma classe, isto pode ser gerenciado pelos prprios mtodos da
classe.
Considere a classe Data que permite livre acesso a seus membros. Seria fcil um
programa cometer os seguintes erros:
Data d = new Data();
d.dia = 32;
d.mes = 2;
d.dia=30;
d.mes = d.mes + 1; // Sem passar de 12 para 1
// e somar 1 ao ano.
Se os dados membros de uma classe no esto expostos o usurio forado a modificar
variveis membro atravs de mtodos. Estes mtodos podem efetuar, ento, validaes e
no permitir os erros acima mencionados.
public void setDia (int umDia)
{ if (umDia > this.diasNoMes())
{ System.err.println (Dia invlido = + umDia);
// Na verdade, deveria gerar uma exceo.
}
else
{ this.dia = umDia;
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 59
O reuso de uma classe viabilizado quando o usurio forado a acessar os dados da
classe atravs de seus mtodos, uma vez que garante que os efeitos colaterais sejam
propriamente tratados. No caso da classe Data, por exemplo, considere como o mtodo
amanha deveria ser construdo.
Se Data fosse inteiramente acessvel, cada usurio da classe teria que incrementar dia e
testar todas as situaes de erro possveis. Forando o usurio da classe a utilizar o
mtodo amanha() fornecido, todos podem estar certos de que os possveis efeitos
colaterais sero sempre tratados corretamente.
Este aspecto de ocultao de dados geralmente referenciado como encapsulamento.
A biblioteca standard da linguagem java fornece milhares de classes para diversos
propsitos tais como: interface com o usurio, network programming, etc. No entanto,
voc ainda tem que criar as suas prprias classes em java, para descrever os objetos
existentes no domnio do problema tratado pela sua aplicao e para adaptar as classes
fornecidas na biblioteca standard para os seus prprios objetivos.
Uma classe, em java, sempre construda com base em outra. Java vem com uma classe
bsica, denominada object, a partir da qual todas as outras so construdas.
Quando voc estende uma classe, a nova classe inicialmente possui todas as propriedades
e mtodos da classe pai. Voc pode escolher se deseja modificar ou simplesmente manter
os mtodos da classe pai. Voc pode, ainda, fornecer novos mtodos que se aplicam
classe filho apenas. O conceito geral de expanso de uma classe base se chama herana.
Encapsulamento outro conceito bsico da orientao a objetos. Formalmente,
encapsulamento no nada mais do que a combinao de dados e comportamento
(mtodos) em um pacote, e a ocultao da implementao deste comportamento, de
forma que o usurio do objeto no saiba como acessar estes dados a no ser atravs de
seus mtodos. Os dados em um objeto so geralmente denominados variveis de instncia
ou campos e as funes e procedimentos pertencentes a uma classe java so seus
mtodos. Um objeto especfico (que uma instncia de uma classe) ter valores
especficos para seus campos, que definem seu estado corrente. Encapsulamento a
maneira de dar ao objeto o seu comportamento de caixa preta. Isto significa que um
objeto pode mudar totalmente a maneira como armazena os seus dados mas, enquanto
continuar a utilizar os mesmos mtodos para manipular os dados, nenhum outro objeto
saber da mudana, nem tampouco se importar com ela.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 60
Relacionamentos entre Classes
Em um sistema de processamento de pedidos os seguintes substantivos nos levam s
classes:
Item
Pedidos
Pagamento
Cliente
A seguir procuramos pelos verbos. Itens so adicionados a pedidos. Pedidos so enviados
ou cancelados. Pagamentos so aplicados a pedidos. Para cada verbo, adicionar, enviar,
cancelar, aplicar, voc deve identificar o objeto responsvel por executar esta tarefa. Por
exemplo, quando um novo item adicionado a um pedido, o objeto pedido deveria ser o
responsvel pela realizao desta tarefa uma vez que ele sabe como armazenar e ordenar
itens. Isto , adicionarItem deveria ser um mtodo da classe Pedido que recebe um objeto
item como parmetro.
Os mais comuns relacionamentos entre classes so:
Utiliza
Contm (has-a)
Herda (is-a)
O relacionamento utiliza o mais bvio e tambm o mais geral. Por exemplo, a classe
Pedido utiliza a classe Cliente, uma vez que objetos Pedidos necessitam acessar objetos
Cliente para verificar a situao de crdito (do cliente). A classe Item, por sua vez no
utiliza a classe Cliente, uma vez que objetos item nunca necessitam se preocupar com
contas de clientes. Logo, uma classe utiliza outra se manipula objetos dela.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 61
Em geral, uma classe A utiliza uma classe B se:
Um mtodo de A envia uma mensagem para um objeto da classe B, ou
Um mtodo de A cria, recebe, ou retorna objetos da classe B.
Tente minimizar o nmero de classes que utilizam outras. Se uma classe A no est
ciente da existncia de uma classe B, uma modificao em B no afetar A. E isto
significa que uma modificao em B no vai introduzir bugs em A.
O relacionamento contm fcil de entender porque concreto. Por exemplo, um
objeto Pedido contm objetos Itens. Naturalmente, contm um caso especial de
utilizao. Se um objeto A contm um objeto B, ento pelo menos um mtodo da classe
A far uso daquele objeto da classe B.
O relacionamento herda significa especializao. Por exemplo, um pedido de entrega
rpida possui mtodos especiais para tratar a prioridade na entrega e um mtodo
diferente para calcular o custo do transporte. No entanto seus demais mtodos, tais como
adicionar um item ao pedido, remover um item do pedido, etc, so herdados da classe
pedido.
Estes trs relacionamentos entre as classes formam os fundamentos do projeto orientado a
objetos. O diagrama de classe mostra as classes e seus relacionamentos. O diagrama da
figura abaixo (que segue a notao da UML) foi gerado atravs da ferramenta Together/J,
uma aplicao Java que tem por objetivo manter sincronizados o diagrama de classes do
seu sistema e seu respectivo cdigo.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 62
Diferenas entre a OOP e as Tcnicas Tradicionais de Desenvolvimento de Software
Na programao orientada ao procedimento comum se identificar as tarefas que devem
ser executadas e ento:
Atravs de refinamentos sucessivos, quebram-se as tarefas a serem executadas em
subtarefas menores, e estas em subtarefas ainda mais simples at que estas subtarefas
estejam simples o suficiente para que possam ser implementadas.
Aps a implementao destas tarefas, elas costumam ser combinadas para formar
procedimentos mais complexos.
A principal caracterstica da OOP que primeiramente isolamos as classes do projeto
para s ento procuramos pelos mtodos das classes. Cada mtodo na OOP associado a
uma classe responsvel por executar a operao.
Outro aspecto importante a questo da herana que no existente na programao
convencional.
Variveis do Tipo Objeto
Na maioria das classes em Java, criamos objetos, instanciamos seus valores iniciais e,
ento, trabalhamos com eles. A classe console uma exceo uma vez que encapsula
apenas funcionalidade, pois no possui dados prprios.
Para acessar objetos, definimos variveis do tipo objeto.
Empregado umEmpregado; // umEmpregado ainda no faz
// referncia a um objeto.
Por exemplo, o comando acima define uma varivel do tipo objeto, que poder
referenciar objetos do tipo Empregado. importante entender que a varivel
umEmpregado no um objeto e, de fato, ainda no faz sequer referncia a um objeto.
Neste ponto do programa o comando
umEmpregado.aumentaSalario(5);
no vai funcionar, uma vez que preciso instanciar o objeto apontado por
umEmpregado.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 63
Para instanciar este objeto utilize o operador new:
umEmpregado = new Empregado();
A partir deste momento ser possvel aplicar os mtodos definidos para Empregado
sobre umEmpregado.
Em muitas situaes ser preciso criar mltiplas instncias de uma nica classe.
Empregado outroEmpregado = new Empregado();
Agora existem dois objetos do tipo Empregado, um vinculado varivel objeto
umEmpregado e outro vinculado varivel objeto outroEmpregado.
Se voc designar uma varivel a outra conforme vem abaixo, ento ambas as variveis
faro referncia ao mesmo objeto.
Empregado outroEmpregado = umEmpregado;
Isto pode provocar um comportamento estranho do programa, pois se voc executar
outroEmpregado.aumentaSalario(5);
o salrio de umEmpregado sofrer o aumento.
Mas e se voc quiser que as variveis umEmpregado e outroEmpregado faam
referncia a objetos diferentes de forma que voc possa modificar um sem alterar o
outro?
Muitas classes possuem um mtodo denominado clone que efetuam uma cpia do objeto
referenciado, de forma que ao se modificar um, o outro no alterado.
possvel designar null a uma varivel objeto para indicar que ela atualmente no faz
referncia a nenhum objeto.
umEmpregado = null;
if (umEmpregado != null) umEmpregado.aumentaSalario(5);
Variveis objeto locais NO so automaticamente inicializadas com null. preciso
inicializ-las com o operador new ou atribuindo-lhes null.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 64
A Classe GregorianCalendar
O comando abaixo faz o seguinte:
1. Cria uma nova instncia da classe GregorianCalendar denominada hoje.
2. Ao mesmo tempo inicializa o estado do objeto hoje para a data corrente (data do
sistema).
GregorianCalendar hoje = new GregorianCalendar();
Tambm possvel criar uma instncia da classe GregorianCalendar com uma data
especfica:
GregorianCalendar umaData = new GregorianCalendar(1999, 11, 31);
Isto cria uma instncia da classe GregorianCalendar denominada umaData com um valor
inicial de 31 de dezembro de 1999. Observe que os meses variam de zero (Janeiro) a 11
(dezembro).
A classe GregorianCalendar , na realidade, uma classe para Data e Hora. Veja o
programa abaixo:
import java.util.*;
public class Datas
{ public static void main(String[ ] args)
{ GregorianCalendar todaysDate = new GregorianCalendar();
int dia = todaysDate.get(Calendar.DAY_OF_MONTH);
int mes = todaysDate.get(Calendar.MONTH);
int ano = todaysDate.get(Calendar.YEAR);
System.out.println(dia + "/" + (mes + 1) + "/" + ano);
GregorianCalendar viradaDoAno2000 =
new GregorianCalendar(1999, Calendar.DECEMBER, 31,
23, 59, 59);
dia = viradaDoAno2000.get(Calendar.DAY_OF_MONTH);
mes = viradaDoAno2000.get(Calendar.MONTH);
ano = viradaDoAno2000.get(Calendar.YEAR);
int hora = viradaDoAno2000.get(Calendar.HOUR);
int minuto = viradaDoAno2000.get(Calendar.MINUTE);
int segundo = viradaDoAno2000.get(Calendar.SECOND);
System.out.println
(dia + "/" + (mes + 1) + "/" + ano + " " +
hora + ":" + minuto + ":" + segundo);
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 65
Observaes:
Calendar.DECEMBER uma constante que pode ser utilizada em vez do nmero 11.
A razo pela qual a data em java representada por uma classe e no por um tipo da
linguagem que existem aspectos relativos a datas que variam de pas para pas.
Assim, cada programador pode, determinar o formato de data que deseja, sem que a
linguagem tenha que prever todos os aspectos de internacionalizao possveis.
Alguns Mtodos Definidos para a Classe GregorianCalendar
GregorianCalendar ()
Constri um objeto que representa a data e hora corrente do sistema.
GregorianCalendar (int year, int month, int date)
Constri um objeto que representa a data fornecida.
GregorianCalendar (int year, int month, int date,
int hour, int minutes, int seconds)
Constri um objeto que representa a data e a hora fornecidas.
boolean equals (Object when)
Compara este objeto calendrio com when e retorna true se o objeto representa o
mesmo ponto no tempo.
boolean before (Object when)
Compara este objeto calendrio com when e retorna true se ele vem antes de when.
boolean after (Object when)
Compara este objeto calendrio com when e retorna true se ele vem depois de when.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 66
int get (int field)
Parmetro: field um dos seguintes
Calendar.YEAR
Calendar.MONTH
Calendar.DAY_OF_MONTH // Dia do Ms
Calendar.DATE // Dia do Ms
Calendar.HOUR
Calendar.MINUTE
Calendar.SECOND
Calendar.AM_PM
Etc
void set (int field, int value)
Designa um valor para um campo especfico.
void set (int year, int month, int date)
Altera os valores para ano, ms e dia.
void set (int year, int month, int date,
int hour, int minutes, int seconds)
Altera os valores de data e hora.
void add (int field, int amount)
Adiciona a determinado campo uma certo tempo.
Observao:
O calendrio juliano termina em 15 de outubro de 1582 s 00:00:00. Neste instante
comea o calendrio gregoriano.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 67
Mtodos para Acesso e Mutao
A classe GregorianCalendar possui um forma atpica de acessar a informao armazenada
em um objeto calendrio. Normalmente uma classe com este objetivo teria mtodos como
getYear, getMonth, etc. No entanto a classe GregorianCalendar possui um nico mtodo
denominado get que pode ser utilizado para recuperar uma grande quantidade de
informao e no apenas o ano ou o ms.
Para selecionar um item que voc deseja recuperar preciso passar uma constante
definida na classe Calendar, tal como: Calendar.MONTH ou
Calendar.DAY_OF_MONTH.
Exemplo:
GregorianCalendar umaData =
new GregorianCalendar(1999, Calendar.DECEMBER, 31, 23, 59, 59);
System.out.println (umaData.get(Calendar.DATE) + "/" +
(umaData.get(Calendar.MONTH)+ 1) + "/" +
umaData.get(Calendar.YEAR));
E para modificar uma data preciso utilizar um dos mtodos set ou o mtodo add.
Exemplo:
GregorianCalendar umaData =
new GregorianCalendar(1999, Calendar.DECEMBER, 31,
23, 59, 59);
umaData.set(Calendar.YEAR, 2000);
Observe que existe uma diferena conceitual entre o mtodo get e os mtodos set e add.
O mtodo get apenas verifica o estado de um objeto e o informa. J os mtodos set e add
modificam o estado de um objeto.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 68
Objetos como Argumentos de Funes
Objetos, em chamadas de funes so, passados por valor e no por referncia. Vejamos
os exemplos abaixo:
Exemplo 1
static void trocaDias (GregorianCalendar a, GregorianCalendar b)
{ GregorianCalendar temp = b;
b = a;
a = b;
}
A chamada da funo abaixo,
GregorianCalendar data1 = new GregorianCalendar (1999, 10, 10);
GregorianCalendar data2 = new GregorianCalendar (1999, 12, 20);
trocaDias(data1, data2);
produzir o seguinte efeito:
Data1 Data2 A B
Logo antes do return 10/10/99 20/12/99 10/10/99 20/12/99
Aps o retorno 10/10/99 20/12/99 20/12/99 10/10/99
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 69
Exemplo 2
import java.util.*;
public class ManipulaDatas
{ static void mudaData(GregorianCalendar d, int somarAnos)
{ int dia = d.get(Calendar.DATE);
int mes = d.get(Calendar.MONTH);
int ano = d.get(Calendar.YEAR);
System.out.println (dia + "/" + (mes + 1) + "/" + ano);
d = new GregorianCalendar(ano + somarAnos, mes, dia);
dia = d.get(Calendar.DATE);
mes = d.get(Calendar.MONTH);
ano = d.get(Calendar.YEAR);
System.out.println (dia + "/" + (mes + 1) + "/" + ano);
}
public static void main (String[] args)
{ GregorianCalendar data1 = new GregorianCalendar (1999, 11, 31);
System.out.println (data1. get(Calendar.DATE) + "/" +
(data1.get(Calendar.MONTH) + 1) + "/" +
data1.get(Calendar.YEAR));
mudaData (data1, 2);
System.out.println (data1.get(Calendar.DATE) + "/" +
(data1.get(Calendar.MONTH) + 1) + "/" +
data1.get(Calendar.YEAR));
}
}
No exemplo acima aparentemente o objeto est sendo modificado dentro do mtodo, no
entanto, como Java nunca passa parmetros de mtodos por referncia, este exemplo no
vai funcionar. A varivel d recebe uma cpia do ponteiro para o objeto referenciado por
data1.
O comando
d = new GregorianCalendar(ano + somarAnos, mes, dia);
instancia um novo objeto e faz d apontar para ele. O objeto apontado por d modificado,
apenas dentro do mtodo, uma vez que d est apontando para um novo objeto
GregorianCalendar. A varivel data1, no mtodo main, continua apontando para o objeto
original. Quando Java termina a execuo do mtodo mudaData a varivel d
abandonada e a memria alocada para ela ser eventualmente recuperada pela funo de
coleta de lixo do Java.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 70
A Classe Date
java.lang.Object
|
+--java.util.Date
|
+--java.sql.Date
Esta classe permite que JDBC identifique a data como uma SQL DATE.
valueOf
public static Date valueOf(String s)
Converte um string no formato java.sql.Date em java.util.Date.
Parmetros: s uma string data no formato "yyyy-mm-dd"
Retorna: um objeto java.sql.Date.
toString()
public String toString()
Formata uma data no formato JDBC.
Returns: um String no formato yyyy-mm-dd
Overrides: efetua o override do mtodo toString da classe java.util.Date
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 71
Exemplo:
String umaData = "1999-05-12";
Date dataAdmissao = Date.valueOf(umaData);
// dataAdmissao pode ser utilizada em um comando SQL Insert
// E para converter um objeto data no formato JDBC para String h
// duas possibilidades:
1.
String dataAdmString = dataAdmissao.toString();
System.out.println ("Data = " + dataString);
2.
df = DateFormat.getDateInstance();
String umStringData = df.format(dataAdmissao);
System.out.println ("Data = " + dataString);
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 72
Construindo suas Prprias Classes
Exemplo 1: Uma classe Empregado.
class Empregado
{ public Empregado (int num, String n, double s)
{ numero = num;
nome = n;
salario = s;
}
public void print()
{ System.out.println (numero + " " + nome + " " + salario);
}
public void aumentaSalario (double percentualDeAumento)
{ salario = salario * (1 + (percentualDeAumento/100));
}
private int numero;
private String nome;
private double salario;
}
import java.util.*;
public class TestaEmpregado
{ public static void main (String[] args)
{ Empregado[] vetEmpregados = new Empregado[3];
vetEmpregados [0] =
new Empregado (10, "Luis Claudio", 3500);
vetEmpregados [1] =
new Empregado (20, "Vinicius Aguiar", 4500);
int i;
for (i = 0; i < 2; i++) vetEmpregados[i].aumentaSalario(5);
for (i = 0; i < 2; i++) vetEmpregados[i].print();
}
}
Exerccio: Acrescente classe abaixo uma data de contratao do empregado utilizando
a classe GregorianCalendar. Acrescente ao construtor desta classe uma data de
contratao e construa mtodos para:
a) permitir que a data de contratao seja alterada.
b) retornar o ano de contratao do empregado.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 73
Soluo: Uma Classe Empregado com uma data de contratao.
import java.util.*;
class Empregado
{ public Empregado (int num, String n, double s,
GregorianCalendar d)
{ numero = num;
nome = n;
salario = s;
dataContratacao = d;
}
public void print()
{ System.out.println (numero + " " + nome + " " + salario + " " +
anoContratacao());
}
public void aumentaSalario (double percentualDeAumento)
{ salario = salario * (1 + (percentualDeAumento/100));
}
public void alteraDataContratacao (int ano, int mes, int dia)
{ dataContratacao.set(Calendar.YEAR, ano);
dataContratacao.set(Calendar.MONTH, mes);
dataContratacao.set(Calendar.DATE, dia);
}
public int anoContratacao()
{ return dataContratacao.get(Calendar.YEAR);
}
private int numero;
private String nome;
private double salario;
private Calendar dataContratacao;
}
import java.util.*;
public class TestaEmpregado
{ public static void main (String[] args)
{ Empregado[] vetEmpregados = new Empregado[3];
vetEmpregados [0] =
new Empregado (10, "Luis Claudio", 3500,
new GregorianCalendar (1989, 10, 1));
vetEmpregados [1] =
new Empregado (20, "Vinicius Aguiar", 4500,
new GregorianCalendar (1992, 11, 6));
int i;
for (i = 0; i < 2; i++) vetEmpregados[i].aumentaSalario(5);
for (i = 0; i < 2; i++) vetEmpregados[i].print();
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 74
Analisando a Classe Empregado
Esta classe possui 4 mtodos:
public Empregado (String n, double s, Day d)
public void print()
public void aumentaSalario (double percentualDeAumento)
public int anoContratacao()
A palavra-chave public indica que qualquer mtodo de qualquer classe que possui acesso
a uma instncia da classe empregado pode chamar o mtodo. Existem 4 nveis de acesso
possveis:
private
protected
public
package (o default, quando no se especifica nada).
A seguir note que existem 4 campos que armazenaro dados que iremos manipular dentro
de uma instncia da classe Empregado:
private String nome;
private double salario;
private Day dataContratacao;
A palavra-chave private indica nenhuma outra classe ter acesso a estes dados a no ser
atravs dos mtodos (public) da classe Empregados. Campos da instncia de uma classe
so geralmente private.
Observe ainda que um dos campos uma instncia da classe GregorianCalendar.
comum classes possurem campos de instncia (instance fields) que so instncias de
classes (class instances).
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 75
Construtores
A seguir vem um exemplo de mtodo construtor. O construtor utilizado para inicializar
os objetos de uma classe. Sua funo principal atribuir valores iniciais s variveis da
instncia.
Por exemplo, quando voc cria uma instncia da classe empregado com o cdigo abaixo:
dataContratacao = new GregorianCalendar(1950, 0, 1);
Empregado numero007 =
new Empregado (James Bond, 100000, dataContratacao);
Voc cria uma instncia com os seguintes dados:
nome = James Bond;
salario = 100000;
dataContratacao = 01/01/1950 // Na realidade um objeto do tipo
// GregorianCalendar com este dado
// encapsulado.
O mtodo new sempre utilizado com o construtor para criar um objeto da classe. Isto o
fora a determinar os valores iniciais dos seus objetos. Em java preciso inicializar as
variveis de instncia de um objeto implicitamente ou explicitamente.
Os Mtodos da Classe Empregado
Observe que os mtodos definidos para a classe Empregado podem acessar, pelo nome,
os campos da instncia definidos como private.
Por exemplo,
public void aumentaSalario (double percentualDeAumento)
{ salario = salario * (1 + (percentualDeAumento/100));
}
estabelece um novo valor para o campo salario, do objeto que executa este mtodo.
J o comando
numero007.aumentaSalario(5);
aumenta em 5% o valor do campo salario do objeto apontado por numero007. Este
mtodo uma funo com dois argumentos: O primeiro argumento, denominado
argumento implcito, o objeto do tipo Empregado que aparece antes do nome do
mtodo. E o segundo argumento (argumento explcito) o nmero entre parntesis que
aparece aps o nome do mtodo.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 76
O mtodo anoContratacao abaixo retorna um valor inteiro, atravs da aplicao de um
mtodo sobre a varivel de instncia dataContratacao. Isto faz sentido uma vez que
dataContratacao uma varivel de instncia da classe GregorianCalendar que, de fato,
possui um mtodo denominado get.
public int anoContratacao()
{ return dataContratacao.get(Calendar.YEAR);
}
Finalmente, vamos examinar um mtodo mais simples denominado getNome:
public String getNome()
{ return nome;
}
Este um exemplo bvio de um mtodo para acesso a uma varivel de instncia, uma vez
que ele trabalha diretamente com um campo da classe. Ele simplesmente retorna o valor
corrente do campo nome. Para quem est implementando a classe muito mais
trabalhoso criar um campo private e um mtodo public do que criar um campo public.
No entanto, isto no gera trabalho para os usurios da classe, j que os programadores
que a utilizam tero de escrever numero007.getNome() em vez de
numero007.nome. O fato que para o mundo exterior classe Empregados nome
read-only, isto , apenas as operaes da classe podem modific-lo. Quando o usurio de
uma classe necessita ler e alterar um campo da classe, preciso, ao criar a classe,
fornecer 3 itens:
Um campo do tipo private.
Um mtodo pblico de acesso informao.
Um mtodo pblico de atualizao da informao.
As vantagens desta estratgia so:
A implementao interna pode ser alterada sem afetar nenhum cdigo alm dos
mtodos da classe.
Os mtodos responsveis por alterar campos ficam responsveis pela validao dos
mesmos.
Cuidado para no escrever um mtodo de acesso que retorne uma referncia para um
objeto mutvel. Por exemplo:
class Empregado
{ . . .
public String getNome();
public Day getDataContratacao();
private String nome;
private double salario;
private GregorianCalendar dataContratacao;
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 77
O cdigo abaixo quebra o encapsulamento:
dataContratacao = new GregorianCalendar(1950, 1, 1);
Empregado numero007 =
new Empregado (James Bond, 100000, dataContratacao);
Empregado lucia = new Empregado (Lucia, 10000,
new GregorianCalendar(1980, 1, 1));
GregorianCalendar d = lucia.getDataContratacao();
d.set(Calendar.YEAR, 1970) // Isto d a lucia mais 10 anos de
// trabalho na empresa. (Diminui a
// data de admisso em 10 anos).
A razo que d e lucia.getDataContratacao() fazem referncia ao mesmo objeto. Ao
modificar d estaremos modificando um estado privado do objeto lucia.
O mtodo getNome no sofre do mesmo mal uma vez que nome um string e strings so
imutveis. No h mtodos para alterar strings. Objetos da classe GregorianCalendar, no
entanto, podem ser modificados atravs do mtodo set.
A soluo para este problema clonar o campo dataContratacao antes de retorn-lo para
o mtodo que faz o acesso. Um clone uma cpia fiel de um objeto que armazenada em
um novo local. Esta tcnica ser discutida mais adiante. O cdigo com a correo seria:
class Empregado
{ . . .
public GregorianCalendar getDataContratacao()
{ return (GregorianCalendar)dataContratacao.Clone(); }
}
Observao:
Sempre utilize um clone quando for necessrio retornar um campo mutvel.
E para atribuir esta nova data ao objeto lucia faa:
lucia.mudaDataContratacao(novaData);
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 78
Mtodos Privados
Mtodos privados s podem ser chamados por outros mtodos da mesma classe. Estes
mtodos no so utilizados diretamente pelos usurios da classe e, caso seja necessrio,
podero ser apagados sem que isto afete as aplicaes.
Mtodos Construtores
Regras para a criao de construtores:
Observaes sobre Construtores:
Sempre possui o mesmo nome da classe.
Pode possuir zero ou mais parmetros.
Sempre chamado com a palavra-chave new. Isto o diferencia dos demais mtodos.
No possvel alterar os valores de campos da instncia atravs de um construtor. Por
exemplo, chamar o mtodo GregorianCalendar como vem a seguir resulta em um
erro: d.GregorianCalendar(1950,1,1).
No tem um valor de retorno. (No se escreve void)
public Empregado (String n, double s, GregorianCalendar d)
possvel ter mais de um construtor por classe. Voc j viu isto nas classes
GregorianCalendar e GregorianCalendar.
Construtores no so herdados.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 79
Exemplos:
GregorianCalendar hoje = new GregorianCalendar();
ou
GregorianCalendar viradaDoMilenio =
new GregorianCalendar(1999, 12, 31);
A possibilidade de vrios mtodos possurem o mesmo nome, mas argumentos diferentes
denomina-se overloading. O interpretador Java fica responsvel por descobrir qual
mtodo deve chamar. Ele (interpretador) seleciona o mtodo que deve ser executado
casando os tipos dos argumentos nos cabealhos dos vrios mtodos com os tipos dos
valores utilizados em uma chamada de mtodo especfica.
Java determina um valor default (zero para nmeros, null para objetos e false para
boleanos) se voc no os inicializa explicitamente. No entanto, esta considerada uma
prtica de programao pobre, logo sempre uma boa prtica de programao inicializar
todos os campos independentemente do construtor utilizado.
Se todos os construtores de uma classe necessitam designar um mesmo valor para uma
varivel de instncia especfica, h uma sintaxe apropriada para esta situao. Basta
designar um valor ao campo dentro da definio da classe.
Para atribuir um mesmo valor para todos as instncias de uma classe independentemente
do construtor utilizado use a sintaxe abaixo. No exemplo abaixo, deseja-se sempre
inicializar um objeto Cliente designando-se o valor RJ para a varivel de instncia
codigoEstado.
class Cliente
{ public Cliente (String n)
{ nome = n;
numeroDaConta = Conta.getNumber();
}
public Cliente (String n, int a)
{ nome = n;
numeroDaConta = a;
}
. . .
private String nome;
private int numeroDaConta;
private int codigoEstado = RJ;
}
No exemplo abaixo, cada objeto Cliente inicializado com um call separado a
Conta.getNumero(), isto , numeroDaConta no recebe uma constante, logo,
sugerimos que esta inicializao seja efetuada dentro do construtor e no fora dele como
vem abaixo:
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 80
class Cliente
{ public Cliente (String n)
{ nome = n;
}
. . .
private String nome;
private int numeroDaConta = Conta.getNumero();
}
Construtores Default
Um construtor default um construtor sem argumentos. Se voc escrever um cdigo para
a sua classe sem nenhum construtor, Java prov um construtor default para voc. Este
construtor default designa valores default para todas as variveis de instncia. Caso voc
crie algum construtor para a sua classe o construtor default (sem argumentos) no ser
criado.
A partir do momento que um construtor criado para a classe Xxxx o construtor default
deixa de existir, logo, a partir deste momento, uma chamada a new Xxxx() causar um
erro de compilao.
Overloading
Em algumas circunstncias voc pode querer escrever vrios mtodos na mesma classe
que fazem basicamente a mesma coisa com diferentes argumentos. Considere um simples
mtodo para imprimir a representao textual do seu argumento. Este mtodo poderia se
chamar print().
Agora suponha que voc necessite de diferentes mtodos print para imprimir cada
varivel membro do tipo int, float e String. Isto razovel, uma vez que diferentes tipos
necessitam de formataes distintas. Voc poderia criar 3 mtodos: printint(),
printfloat() e printString().
Java permite, no entanto, que voc reutilize um mesmo nome de mtodo em mais de um
mtodo. Por exemplo:
public void print(int i);
public void print(float f);
public void print(String s);
Quando voc escreve cdigo para chamar um destes mtodos, o mtodo apropriado
escolhido de acordo com o tipo do argumento que voc fornece.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 81
Duas regras se aplicam para mtodos overloaded:
1. A lista de argumentos deve ser diferente para que o mtodo correto seja chamado.
2. O tipo de retorno pode ser diferente, mas isto no suficiente. A lista de argumentos
deve ser diferente.
Exemplo de Overloading
import java.util.*;
import corejava.*;
public class TestaEmpregado
{ public static void main (String[] args)
{ Empregado[] vetEmpregados = new Empregado[3];
vetEmpregados [0] =
new Empregado ("Luis Claudio", 3500,
new GregorianCalendar (1989, 10, 1));
vetEmpregados [1] =
new Empregado ("Vinicius Aguiar", 4500,
new GregorianCalendar (1992, 12, 6));
vetEmpregados [2] =
new Empregado ("Luciana Arruda", 2500,
new GregorianCalendar (1993, 1, 12));
int i;
for (i = 0; i < 3; i++)
{ vetEmpregados[i].print(vetEmpregados[i].getNome());
vetEmpregados[i].print(vetEmpregados[i].getSalario());
}
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 82
import java.util.*;
class Empregado
{ public Empregado (String n, double s, GregorianCalendar d)
{ nome = n;
salario = s;
dataContratacao = d;
}
public void print()
{ System.out.println (nome + " " + salario + " " +
anoContratacao());
}
public void aumentaSalario (double percentualDeAumento)
{ salario = salario * (1 + percentualDeAumento) / 100;
}
public void alteraDataContratacao (int ano, int mes, int dia)
{ dataContratacao.set(Calendar.YEAR, ano);
dataContratacao.set(Calendar.MONTH, mes);
dataContratacao.set(Calendar.DATE, dia);
}
public int anoContratacao()
{ return dataContratacao.get(Calendar.YEAR);
}
public String getNome()
{ return nome;
}
public double getSalario()
{ return salario;
}
public void print(int i)
{ System.out.println (i);
}
public void print(String s)
{ System.out.println (s);
}
public void print(float f)
{ System.out.println (f);
}
public void print(double d)
{ System.out.println (d);
}
private String nome;
private double salario;
private GregorianCalendar dataContratacao;
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 83
O Objeto this
Ocasionalmente voc pode desejar acessar um objeto por inteiro, e no uma varivel de
instncia particular. Neste caso Java prov uma forma conveniente para realizar este
acesso atravs da palavra-chave this. Em um mtodo a palavra-chave this referencia o
objeto no qual o mtodo opera.
Em uma funo tradicional os dados que devem ser manipulados no referenciados
atravs de nomes de argumentos passados para a funo. Em Java no h nomes de
argumentos. No entanto voc pode referenciar o objeto que o alvo da operao atravs
da palavra-chave this. Por exemplo:
Em linguagens que no suportam esta associao entre dados e cdigo, a declarao do
mtodo amanha especifica uma data em particular que deve ser incrementada em um dia.
Por exemplo:
Uma funo convencional:
umaData = amanha(Data d);
A chamada a um mtodo Java:
Data d = new Data(); // Um objeto do tipo Data (referenciado
// por d) contendo a data de hoje
// criado.
d.amanha();
Um mtodo Java com a palavra-chave this:
public class Data
{ public void amanha()
{ this.day = this.day + 1; // Simplificao ...
}
private int dia, mes, ano;
}
Java automaticamente associa todas as referncias a variveis e mtodos palavra-chave
this, logo utilizar a palavra-chave this como utilizado acima uma redundncia.
public class Data
{ public void amanha()
{ day = day + 1; // Simplificao ...
}
private int dia, mes, ano;
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 84
H ocasies, no entanto, em que a palavra-chave this no redundante. Por exemplo,
voc pode querer chamar um mtodo de uma classe completamente diferente e passar
uma instncia de um objeto como argumento.
Exemplo: A implementao de uma associao entre Empregados e Departamentos.
H um outro significado para a palavra-chave this. Se o primeiro comando de um
construtor possui a forma this (. . .), ento o construtor chama outro construtor da mesma
classe.
Exemplo:
class Cliente
{ public Cliente (String n)
{ this (n, Conta.getNumero(nc));
}
public Cliente (String n, int a)
{ nome = n;
numeroDaConta = nc;
}
. . .
}
Quando voc chama new Cliente (Luiza Thom), ento o construtor
Cliente (String) chama o construtor Cliente (String, int).
O Mtodo toString
Muitas classes em Java possuem um mtodo chamado toString() que retorna um string
que descreve o objeto. Se voc passar um objeto (por inteiro) para o mtodo
System.out.println, este mtodo chamar o mtodo toString definido na classe deste
objeto e ser impresso o string que descreve o objeto. Esta uma estratgia interessante
ao se fazer debug de uma aplicao.
Exemplo:
System.out.println (nomeDoObjeto);
// Funciona como se tivesse sido escrito:
// System.out.println (nomeDoObjeto.toString());
Em vez de:
System.out.println (nomeDoObjeto.getNomeDeUmAtributoPrivate);
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 85
Blocos de Inicializao
Voc j viu duas maneiras de inicializar um campo:
designando um valor em um construtor.
designando um valor em uma declarao. (uma cte ou uma chamada a um mtodo)
H uma terceira maneira, denominada bloco de inicializao. Estes blocos so executados
sempre que um objeto da classe construdo.
Exemplo:
class Cliente
{ public Cliente (String n)
{ nome = n;
}
. . .
// Um bloco de inicializao
static
{ numeroDaConta = Conta.getNumero();
}
. . .
}
Este mecanismo nunca necessrio, embora comum. geralmente mais claro colocar o
cdigo de inicializao dentro de um construtor. No entanto, para inicializar variveis
estticas, um bloco de inicializao de variveis estticas pode ser til.
Ordem de execuo quando um construtor chamado:
1. Todos os campos so inicializados, na ordem em que foram declarados. Valores
default so assumidos, quando valores iniciais no tiverem sido especificados.
2. Todos os blocos de inicializao so executados, na ordem em que aparecem.
3. Se a primeira linha de um construtor chama outro construtor, ento aquele construtor
executado.
4. O corpo do construtor executado.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 86
Mtodos e Campos Estticos
Campos estticos no mudam de uma instncia de uma classe para outra, logo voc deve
pensar neles como campos pertencentes classe. Da mesma forma, mtodos estticos
pertencem classe e no podem ser executados sobre nenhuma instncia da classe. Por
exemplo, os mtodos da classe Console, assim como todos os mtodos da classe Math.
Exemplos:
double x = Console.readDouble();
double x = Math.pow (3, 4);
J vimos tambm a utilizao de campos estticos:
Math.PI
System.out
So campos estticos das classes Math e System.
Como Inicializar um Campo Esttico
H duas maneiras:
Fornecendo um valor inicial.
Exemplo:
public static final CM_POR_POLEGADA = 2.54;
Atravs de um bloco de inicializao esttico. Este mtodo utilizado quando a
inicializao no cabe em uma nica expresso. A inicializao das variveis estticas
ocorre quando a classe carregada pela primeira vez. Primeiramente todas as
variveis estticas so inicializadas na ordem em que foram declaradas e
posteriormente so executados todos os blocos estticos de inicializao.
Exemplo 1:
static double[] buffer = new double[BUFFER_SIZE];
static
{ int i;
for (i = 0; i < buffer.length; i++)
buffer[i] = java.lang.Math.random();
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 87
Exemplo 2:
Um outro exemplo de bloco esttico o mtodo main de uma classe. Seu header possui a
forma:
public static void main (String[] args)
Como o mtodo main esttico, no necessrio instanciar a classe para se poder cham-
lo. Ao se executar java abc o interpretador java simplesmente inicia o mtodo main
sem criar um objeto da classe abc. Por esta razo, o mtodo main s pode acessar
campos de instncia estticos. No raro o mtodo main criar um objeto da sua prpria
classe, conforme exemplo abaixo:
public class Aplicacao
{ . . .
public static void main (String[] args)
{ Aplicacao a = new Aplicacao();
// Agora possvel chamar o mtodo a.xyz();
}
}
Quando o programa comea, o mtodo main, ao ser executado, cria um objeto do tipo
Aplicacao. A partir deste momento ele pode invocar mtodos de instncia sobre o objeto
criado.
Como Compilar Programas
Para compilar vrias classes que comeam com a letra C, por exemplo digite:
Javac C*.java
Uma outra alternativa de compilao compilar apenas a classe que se deseja executar.
Quando o compilador encontrar uma referncia a outra classe (Xxxx, por exemplo) ele ir
procurar por um arquivo denominado Xxxx.class. Se o arquivo no for encontrado, o
arquivo Xxxx.java ser procurado e, ento, compilado. E tem mais: se o timestamp do
arquivo Xxxx.java for mais novo do que o timestamp do arquivo Xxxx.class, Xxxx.java
ser recompilado.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 88
Packages
Java nos permite agrupar classes em uma coleo denominada package. Packages so
utilizados com o objetivo de organizar o seu trabalho e para separar o seu cdigo das
bibliotecas de cdigo fornecidas por terceiros. Por exemplo, a biblioteca standard de Java
distribuda com uma srie de packages, como, java.lang, java.util,
java.net, etc. Como voc j deve ter notado, possvel organizar os packages
utilizando nveis de aninhamento. Todos os packages standard de Java esto dentro da
hierarquia de packages java.
Uma razo para aninhar pacotes garantir a unicidade dos nomes utilizados para nomear
pacotes e classes. Por exemplo, voc poderia criar um package denominado sistemas e
dentro de sistemas seriam criados outros, um para cada aplicao.
Exemplo:
sistemas
comuns
Aqui seriam criadas as classes comuns a todos os sistemas.
contas.receber
Aqui seriam criadas as classes do sistema de Contas a receber
contas.pagar
Idem Contas a Pagar.
faturamento
Idem Faturamento.
fluxocaixa
Idem Fluxo de Caixa.
Quando se escreve um package preciso por o nome do pacote no topo do arquivo fonte,
antes do cdigo que define as classes existentes no package.
Por exemplo:
Package faturamento;
Isto significa que o arquivo .java faz parte do package denominado faturamento. Este
comando deve ser o primeiro comando em um arquivo. Antes dele, s comentrios.
Se voc no colocar este comando em um arquivo fonte, Java adicionar as classes
existentes neste arquivo a um package conhecido como default package. O default
package no possui um path, logo, se o diretrio corrente (.) faz parte do class path, ento
as classes sem declarao de package no diretrio corrente automaticamente se tornam
parte do default package. Todas as classes existentes no class path fazem parte do default
package.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 89
Utilizando Packages
H duas maneiras de utilizar as classes pblicas de um package:
Fornea o nome completo do package.
Exemplo:
java.util.GregorianCalendar hoje = new java.util.GregorianCalendar();
Indique em que packages as classes se encontram.
Exemplo:
import java.util.*
GregorianCalendar hoje = new GregorianCalendar();
Observaes:
O asterisco (*) utilizado para importar as classes pertencentes a um nico package.
No possvel utilizar import java.* esperando importar todos os packages cujos
nomes comeam por java.
Se duas classes possuem o mesmo nome, embora em packages diferentes, no
possvel importar ambas.
Como o Compilador Localiza os Packages
O compilador do JDK e a maioria dos compiladores Java armazenam os packages em
subdiretrios do sistema de arquivos ou em arquivos .zip ou .jar. Se voc utiliza o
JDK para Windows, o class path determinado pela varivel de ambiente CLASSPATH
conforme vem abaixo:
SET CLASSPATH=.;C:\JDK\LIB\CLASSES.ZIP;C:\COREJAVA
O Escopo de um Package
Se um mtodo ou varivel definido sem um access modifier (public, private, etc)
ento ele poder ser acessado por todos os mtodos no mesmo package. Para os mtodos
este default razovel, mas para variveis, no, uma vez que se voc esquecer de definir
uma varivel como private ela ficar visvel dentro de todo o package, o que quebra o
encapsulamento.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 90
Como a classe TestaEmpregado no est dentro de um package, ela se encontra dentro do
package default que formado pelo CLASSPATH.
import java.util.*;
public class TestaEmpregado
{ public static void main (String[] args)
{ // Projeto umProjeto = new Projeto("Bacuri");
Empregado [] empregados = new Empregado[2];
Empregado vinicius = new Empregado ("Vinicius Aguiar", 4500,
new GregorianCalendar (1992, 6, 13));
Empregado carlos = new Empregado ("Carlos Ribeiro", 5500,
new GregorianCalendar (1993, 7, 14));
empregados[0] = carlos;
empregados[1] = vinicius;
int n = FuncoesGerais.encontrar(empregados, carlos);
if (n==-1)
System.out.println("No achou");
else
System.out.println("Achou na posio: " + n);
}
}
Examinando a classe abaixo voc ver que ela no se encontra dentro de nenhum
package, logo, o mtodo encontrar s poder ser executado (isto , s ser
encontrado) caso a classe onde se encontra a chamada ao mtodo encontrar tambm
estiver no package default.
Quando no se especifica nada para um mtodo o mtodo visvel no package.
O package default o formado pelo contedo do CLASSPATH. Se uma classe est dentro
de um package e chama um mtodo de outra classe, no basta que esta outra esteja no
CLASSPATH. preciso que ela esteja dentro de um package no class path. O package
default no ser pesquisado, a menos que a classe que chama o mtodo da outra tambm
esteja no package default.)
public class FuncoesGerais
{ static int encontrar (Object[] a, Object b)
{ int i;
for (i = 0; i < a.length; i++)
if (a[i].equals(b)) return i;
return -1; // Caso no encontre.
}
}
Quando voc utiliza a declarao de um package voc no necessita importar o mesmo
package ou qualquer outro elemento do package. Lembre-se que o comando import
utilizado para trazer classes em outros packages.
Como o Compilador Localiza os Arquivos .java
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 91
Atravs do CLASSPATH ou atravs do parmetro sourcepath. O parmetro d indica
onde os arquivos .class devem ser armazenados.
javac -sourcepath c:\java\packages -d c:\java\classes BemVindo.java
O parmetro classpath especificado abaixo indica ao interpretador onde encontrar o
arquivo .class.
java -classpath c:\java\classes BemVindo
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 92
HERANA
Neste captulo vamos nos concentrar nas tcnicas de derivao de uma classe a partir de
outra. Atravs da herana possvel reutilizar ou modificar mtodos de classes existentes,
assim como adicionar novos campos de instncia e mtodos nova classe.
Java permite que uma classe estenda apenas uma outra classe. Esta restrio conhecida
como herana simples. Mais adiante examinaremos a facilidade denominada
interface que permite alguns dos benefcios da herana mltipla.
Vamos voltar a examinar a classe Empregado. Suponha que voc trabalha em uma
companhia onde os gerentes so tratados de maneira substancialmente diferente dos
demais empregados. Seus salrios so calculados de maneira diferente, possuem direito a
uma secretria, etc. Neste caso, ser preciso criar uma classe Gerente e adicionar
funcionalidade a ela. Note que existe um relacionamento do tipo -um entre Gerente e
Empregado, isto , todo gerente um empregado.
Classe Empregado
import java.util.*;
class Empregado
{ public Empregado (String n, double s, GregorianCalendar d)
{ nome = n;
salario = s;
dataContratacao = d;
}
public void print()
{ System.out.println (nome + " " + salario + " " +
anoContratacao());
}
public void aumentaSalario (double percentualDeAumento)
{ salario = salario * (1 + percentualDeAumento) / 100;
}
public int anoContratacao()
{ return dataContratacao.getYear();
}
public String getNome()
{ return nome;
}
public String setNome(String n)
{ nome = n;
}
private String nome;
private double salario;
private GregorianCalendar dataContratacao;
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 93
Classe Gerente
import corejava.*;
class Gerente extends Empregado
{ public Gerente (String n, double s, GregorianCalendar d)
{ super(n, s, d);
nomeDaSecretaria = " ";
}
public void aumentaSalario (double percentualDeAumento)
{ // adiciona 0,5 % de bonus para cada ano de servio
GregorianCalendar hoje = new GregorianCalendar();
double bonus = 0.5 * (hoje.getYear() - anoContratacao());
super.aumentaSalario (percentualDeAumento + bonus);
}
public String getNomeDaSecretaria()
{ return nomeDaSecretaria;
}
public void setNomeDaSecretaria(String nome)
{ nomeDaSecretaria = nome;
}
private String nomeDaSecretaria;
}
Observaes:
A palavra-chave extends indica que voc est criando uma nova classe a partir de
uma classe existente. A classe existente denominada superclasse, classe base ou
classe pai. A nova classe denominada subclasse, classe derivada ou classe filho.
A seguir observe o construtor da classe Gerente:
public Gerente (String n, double s, GregorianCalendar d)
{ super(n, s, d);
nomeDaSecretaria = " ";
}
A palavra-chave super se refere superclasse (Empregado), e a linha super(n, s, d);
chama o construtor da classe Empregado passando os parmetros n, s e d. Se o
construtor da subclasse no chamar explicitamente o construtor da superclasse, o
construtor default (sem parmetros) ser chamado. Neste caso, se no existir um
construtor default, ocorrer um erro de compilao. Logo, a menos que a subclasse
esteja satisfeita com o construtor default da superclasse, ela sempre dever utilizar a
palavra chave super com os parmetro apropriados para chamar o construtor
desejado.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 94
O compilador exige que a chamada com a palavra-chave super seja o primeiro
comando do construtor da subclasse.
Uma subclasse geralmente possui mais campos de instncia do que a superclasse,
logo, seguindo a boa prtica de programao, designamos um string vazio para o
campo de instncia nomeDaSecretaria a fim de inicializ-lo. (Por default ele seria
inicializado com nulo.)
Dentre os vrios mtodos existentes na classe Empregado, muitos no so redefinidos
na classe Gerente. Deve-se indicar apenas as diferenas entre a superclasse e a
subclasse. Por exemplo, no foi preciso fornecer uma nova definio do mtodo
getNome uma vez que este mtodo (na superclasse) j faz o que desejamos. O fato da
funcionalidade comum ter sido colocada na superclasse (factoring) essencial para o
bom uso da herana na programao orientada a objetos.
Por outro lado, note que foi fornecida uma nova definio do mtodo aumentaSalario,
uma vez que desejamos que este mtodo funcione diferentemente para gerentes e
empregados comuns.
public void aumentaSalario (double percentualDeAumento)
{ // adiciona 0,5 % de bnus para cada ano de servio
GregorianCalendar hoje = new GregorianCalendar();
double bonus = 0.5 * (hoje.getYear() - anoContratacao());
super.aumentaSalario (percentualDeAumento + bonus);
}
Suponhamos, agora, que a empresa resolva conceder um aumento de 5% para todos
os seus funcionrios. Para os gerentes, no entanto, este aumento calculado da
seguinte forma:
Primeiramente calculado um percentual de bnus em funo do tempo de casa.
Em seguida, em funo da utilizao da palavra-chave super, chamado o mtodo
aumentaSalario da superclasse que s ento calcular o aumento a ser concedido
ao gerente.
Note que o mtodo aumentaSalario no possui acesso direto aos campos de instncia
privados da superclasse. Isto significa que o mtodo aumentaSalario da classe
Gerente no pode mudar diretamente o campo salrio, embora todo objeto gerente
possua um campo salrio. Se os mtodos da classe Gerente necessitarem acessar os
campos de instncia privados da classe Empregado, eles tero que fazer o que todos
os outros mtodos fazem: utilizar a interface pblica da superclasse. Neste caso, o
mtodo aumentaSalario da classe Empregado.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 95
Exemplo de Utilizao das Classes Empregado e Gerente:
Em linguagens orientadas a objetos possvel criar colees de coisas que possuem uma
classe ancestral comum. Podemos, por exemplo, escrever um mtodo de ordenao para
ordenar empregados por idade ou salrio sem termos de nos preocupar se um empregado
gerente ou no.
Como em Java toda classe uma subclasse de Object, voc pode utilizar um array de
Objects como um container para qualquer tipo de objeto. A nica coisa que no pode ser
adicionada a um array de Objects so variveis primitivas. Melhor ainda do que utilizar
um array de Object seria utilizar a classe Vector que foi projetada para armazenar
colees de objetos heterogneos.
import java.util.*;
public class TestaEmpregadoGerente
{ public static void main (String[] args)
{ Gerente mandaChuva =
new Gerente ("Ricardo Silva", 7500,
new GregorianCalendar(1987, 12, 15));
mandaChuva.setNomeDaSecretaria ("Claudia Lins");
// Cadastramos 3 empregados:
Empregado[] vetEmpregados = new Empregado[3];
vetEmpregados [0] = mandaChuva;
vetEmpregados [1] =
new Empregado ("Claudia Lins", 2000,
new GregorianCalendar (1992, 12, 6));
vetEmpregados [2] =
new Empregado ("Luciana Arruda", 2500,
new GregorianCalendar (1993, 1, 12));
int i;
System.out.println ("Empregados e Salarios antes do aumento");
for (i = 0; i < 3; i++) vetEmpregados[i].print();
System.out.println ("");
for (i = 0; i < 3; i++) vetEmpregados[i].aumentaSalario(5);
System.out.println ("Empregados e salarios apos o aumento");
for (i = 0; i < 3; i++) vetEmpregados[i].print();
System.out.println ("");
System.out.println ("A secretaria do departamento se chama " +
mandaChuva.getNomeDaSecretaria());
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 96
Observaes:
Note que vetEmpregados [1] e vetEmpregados [2] recebem aumento de 5% uma vez
que eles so objetos do tipo empregado. J vetEmpregados [0] um objeto do tipo
gerente, e por isso obtm um aumento maior.
Como no foram definidos mtodos de impresso especficos para a classe Gerente,
os trs empregados so impressos com o mtodo de impresso da classe Empregados.
Trabalhando com Subclasses
No exemplo abaixo as variveis vetEmpregados[0] e mandaChuva apontam para a
mesma rea de memria. No entanto, para o compilador vetEmpregados [0] apenas um
objeto do tipo empregado.
Empregado[] vetEmpregados = new Empregado[3];
Gerente mandaChuva =
new Gerente ("Ricardo Silva", 7500,
new GregorianCalendar(1987, 12, 15));
vetEmpregados [0] = mandaChuva;
Um objeto da subclasse pode ser passado como argumento para qualquer mtodo que
espere receber um objeto da superclasse. J o contrrio no possvel (necessita de um
cast). Por exemplo, o comando abaixo resulta em um erro uma vez que o objeto da
subclasse pode possuir mais campos do que o objeto da superclasse.
mandaChuva = vetEmpregados [i]; // Seria preciso fazer um cast
Uma subclasse no pode possuir menos campos do que sua superclasse. No h como
retirar campos de uma subclasse. Campos podem apenas ser acrescentados.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 97
Polimorfismo
Na OOP estamos sempre enviando mensagens para objetos, solicitando que tarefas sejam
executadas. Quando voc envia uma mensagem solicitando que uma subclasse execute
um mtodo com determinados parmetros acontece o seguinte:
A subclasse checa se ela possui um mtodo com o mesmo nome e com exatamente os
mesmos parmetros. Caso possua, o mtodo executado. Caso no possua, a classe pai
fica responsvel por manipular a mensagem, isto , por procurar em seu domnio por um
mtodo com o mesmo nome e com exatamente os mesmos parmetros. Se o mtodo for
encontrado, ser executado.
Como a manipulao desta mensagem pode continuar subindo na cadeia da hierarquia,
classes pais so checadas at que a cadeia termine ou at que o mtodo seja encontrado.
Note que mtodos com o mesmo nome podem existir em muitos nveis na cadeia
hierrquica. Isto nos leva a uma regra fundamental relativa a herana: Um mtodo
definido em uma subclasse com o mesmo nome e lista de parmetros de um mtodo
definido em uma classe ancestral, esconde o mtodo da classe ancestral da subclasse. Por
exemplo, o mtodo aumentaSalario da classe Gerente chamado em vez do mtodo
aumentaSalario da classe Empregado quando voc envia uma mensagem para um objeto
da classe Gerente.
O nome e a lista de parmetros de um mtodo costumam ser conhecidos como a
assinatura do mtodo. Logo os mtodos aumentaSalario (double) e aumentaSalario
(boolean) so mtodos com o mesmo nome mas com assinaturas diferentes. O tipo do
dado retornado pelo mtodo no faz parte da assinatura. Em java, uma superclasse no
pode possuir um mtodo com a mesma assinatura de um mtodo de uma subclasse mas
com tipos de retorno diferentes.
A idia por traz do polimorfismo que objetos pertencentes a classes diferentes (em uma
mesma hierarquia) podem responder diferentemente a mensagens iguais.
A tcnica utilizada para se conseguir que um mtodo polimrfico seja executado se
chama late binding. Isto significa que o compilador no gera o cdigo para a chamada
de um mtodo em tempo de compilao. Sempre que um mtodo aplicado a um objeto
o compilador gera o cdigo necessrio para calcular que mtodo deve ser chamado. Este
processo conhecido como dynamic binding ou dynamic dispatch. O mecanismo
tradicionalmente utilizado para a chamada de mtodos conhecido como static
binding.
Em Java no necessrio declarar um mtodo como virtual (como ocorre em C++ e em
Pascal). Este comportamento o default. Se voc no quer que uma funo seja virtual,
declare-a como final.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 98
Polimorfismo em uma hierarquia de herana, s vezes chamado de verdadeiro
polimorfismo para distingui-lo do outro tipo mais limitado denominado overloading que
no resolvido dinamicamente, e sim estaticamente em tempo de compilao.
O que menos bvio o que acontece quando temos:
Empregado[] vetEmpregados = new Empregado[2];
vetEmpregados [0] =
new Gerente ("Ricardo Silva", 7500,
new GregorianCalendar(1987, 12, 15));
vetEmpregados [1] =
new Empregado ("Luis Alberto", 2500,
new GregorianCalendar(1988, 10, 11));
vetEmpregados[0].aumentaSalario(5);
vetEmpregados[1].aumentaSalario(5);
Neste caso, para cada posio do vetor vetEmpregados, teremos o comportamento
associado ao tipo real de cada objeto armazenado em cada posio do vetor (runtime
type). Esta uma outra importante caracterstica do polimorfismo e conhecida como
virtual method invocation.
Em C++ voc apenas obtm este comportamento se definir o mtodo como virtual. Em
linguagens puras orientadas a objetos, no entanto, isto no normal. C++ faz isso,
naturalmente, para aumentar o desempenho.
Voc ir s vezes ouvir que em linguagens orientadas a objetos so passadas mensagens a
objetos solicitando que sejam executadas determinadas aes. Uma forma interessante de
pensar sobre chamadas a mtodos virtuais imaginar que o mtodo uma instruo
passada para o objeto. Logo, em vez de dizer CPU para executar um trecho de cdigo,
voc diz a um objeto faa xxx para mim. Este modelo faz com que seja fcil entender
que o comportamento ser sempre o comportamento adequado associado a um objeto
real, de um determinado tipo.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 99
Como Impedir a Herana
Java permite que a palavra-chave final seja aplicada a classes. Se isto for feito, a classe
no poder ser estendida. A classe java.lang.String, por exemplo uma classe final. Isto
foi feito por questes de segurana, uma vez que isto garante que se um mtodo possui
uma referncia a um String, se trata realmente de um String e no alguma subclasse que
pode ter sido acrescentada maliciosamente visando modificar seu comportamento.
Exemplo:
final class Vendedor
{ . . .
}
Tambm possvel fazer com que um mtodo no possa ser sobreposto por outro de uma
subclasse. Basta defini-lo como final.
Todos os mtodos em uma classe final so automaticamente final.
Mtodos marcados como static ou private so automaticamente final uma vez
que em ambos os casos o dynamic binding no pode ser utilizado.
Razes para tornar um mtodo final:
1. Eficincia. O dynamic binding leva mais tempo do que o static binding. Se um
mtodo final o compilador faz o seguinte:
Exemplo:
Se e.getNome() final o compilador pode substituir este cdigo por e.nome.
Assim voc tem o benefcio do acesso direto s variveis de instncia sem quebrar o
encapsulamento.
2. Segurana. A flexibilidade do mecanismo de dynamic dispatch significa que voc
no possui controle sobre o que acontece quando voc chama um mtodo. Quando
voc envia uma mensagem como e.getNome(), possvel que e seja um objeto de
uma classe derivada que redefiniu o mtodo getNome() para retornar um string
completamente diferente, por exemplo. Tornando o mtodo final, o chamador de
um mtodo sabe que o comportamento que ir ocorrer o esperado (o original) e no
um outro qualquer.
Toda classe que no faz sentido derivar deve ser definida como final, por questo de
eficincia.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 100
Instanceof
Se um mtodo recebe um objeto do tipo Empregado, este empregado pode ser um simples
empregado, um Gerente ou um Vendedor. Se voc desejar, possvel verificar o tipo de
um objeto atravs de instanceof:
public void metodo(Empregado e)
{ if (e instanceof Gerente)
{ // Processamento de gerente
}
else if (e instanceof Vendedor)
{ // Processamento de Vendedor
}
else
{ // Processamento de empregado comum
}
}
Casting
o processo de converso de um tipo bsico em outro.
Exemplo:
double x = 3.45;
int nx = (int) x;
Em situaes em que um mtodo recebe uma referncia a uma classe pai, e voc
determinou (atravs de instanceof) que o objeto de uma subclasse particular possvel
restaurar toda a funcionalidade do objeto efetuando um cast na referncia.
Por exemplo:
public void metodo(Empregado e)
{ if (e instanceof Gerente)
{ System.out.println ("O nome da secretria : " +
((Gerente)e).getNomeDaSecretaria();
}
// O resto do cdigo
}
Sem efetuar o teste com instanceof corre-se o risco do cast falhar.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 101
Regras de converso de classes:
cast para cima na hierarquia das classe sempre legal. Neste caso no necessrio
utilizar o operador cast, bastando uma simples designao.
Para efetuar um cast para baixo, preciso que a classe destino da converso seja uma
subclasse da classe de origem. Esta verificao efetuada em tempo de compilao.
Se o compilador permitiu o cast, ento o tipo da referncia verificado em tempo de
execuo. Se o operador instanceof no foi utilizado e o objeto que est sofrendo o
cast no possui de fato o tipo especificado, ser gerada uma exceo.
Gerente g = (Gerente) e;
No exemplo abaixo preciso converter um objeto empregado em gerente para que se
possa acessar qualquer dos seus campos (e mtodos).
Como voc sabe, em Java toda varivel objeto possui um tipo. O tipo descreve o tipo de
objeto a que a varivel se refere e o que pode ser feito com ela. No exemplo abaixo,
vetEmpregados[i] se refere a um objeto Empregado (logo, tambm pode referenciar um
objeto Gerente).
Empregado[] vetEmpregados = new Empregado[3];
Se voc designar um objeto de uma subclasse a uma varivel de uma superclasse, como
voc est prometendo fazer com ele menos do que permitido, o compilador lhe permite
fazer isso. Por outro lado, se voc designar um objeto de uma superclasse a uma varivel
de uma subclasse, como voc est dizendo que pretende fazer com ele mais do que a
superclasse permite, ser preciso confirmar esta converso com a utilizao do cast
(Subclasse).
E o que acontece se ao executar o comando abaixo voc estiver mentindo sobre o
contedo do objeto?
Gerente mandaChuva = (Gerente) vetEmpregados[1];
Ocorrer um erro de execuo, isto , ser gerada uma exceo. Para evitar este erro voc
deveria fazer o seguinte:
if (vetEmpregados[1] instanceof Gerente)
{ mandaChuva = (Gerente) vetEmpregados[1];
. . .
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 102
Resumindo:
possvel utilizar o cast apenas dentro de uma hierarquia de herana.
Utilize o instanceof para verificar a hierarquia antes de converter um objeto de uma
superclasse para uma subclasse.
Na verdade, converter o tipo de um objeto atravs de um cast no , geralmente, uma boa
prtica de programao. No exemplo apresentado no preciso converter um objeto
Empregado em um objeto Gerente para a maioria dos fins. Por exemplo, o mtodo
aumentaSalario funcionar corretamente em ambos os tipos em funo do dynamic
binding. A nica razo para se realizar o cast utilizar um mtodo pertencente apenas
classe Gerente. Por exemplo, getNomeDaSecretaria(). Se for importante obter o nome da
secretaria para um objeto do tipo Empregado, voc poderia reprojetar a classe e adicionar
um mtodo getNomeDaSecretaria, que simplesmente retorna um string vazio. Isto faz
mais sentido do que ter que descobrir que posies do array armazenam que tipo de
objeto.
Classe Gerente
Exerccio: O que preciso fazer na classe Gerente abaixo para armazenarmos uma
referncia para a secretria e no apenas o seu nome?
import java.util.*;
class Gerente extends Empregado
{ public Gerente(String n, double s, GregorianCalendar d)
{ super(n, s, d);
}
public void aumentaSalario(double percentual)
{ // adiciona 0.5% de bonus para cada ano de servio
GregorianCalendar hoje = new GregorianCalendar();
double bonus = 0.5 * (hoje.getYear() - anoContratacao());
super.aumentaSalario(percentual + bonus);
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 103
Esta abordagem reflete melhor a realidade do que simplesmente utilizar o nome da
secretria. O registro de Empregado para a secretria pode agora ser processado sem a
necessidade de fazer uma busca no array vetEmpregados.
Uma vez feito isto, voc deve ter em mente que o objeto Gerente agora contm uma
referncia para o objeto Empregado, que descreve a secretria.
Classe Empregado
import corejava.*;
class Empregado
{ public Empregado (String n, double s, GregorianCalendar d)
{ nome = n;
salario = s;
dataContratacao = d;
}
public void print()
{ System.out.println (nome + " " + salario + " " +
anoContratacao());
}
public void aumentaSalario (double percentualDeAumento)
{ salario = salario * (1 + percentualDeAumento) / 100;
}
public int anoContratacao()
{ return dataContratacao.getYear();
}
public String getDataContratacao()
{ int dia = dataContratacao.get(Calendar.DAY_OF_MONTH);
int mes = dataContratacao.get(Calendar.MONTH);
int ano = dataContratacao.get(Calendar.YEAR);
return (dia + "/" + (mes + 1) + "/" + ano);
}
public String getNome()
{ return nome;
}
public double getSalario()
{ return salario;
}
private String nome;
private double salario;
private GregorianCalendar dataContratacao;
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 104
Exemplo de Utilizao das Classes Empregado e Gerente:
Exerccio: Escreva o cdigo necessrio para obter e imprimir o nome de cada empregado
seguido do nome da secretria, quando se tratar de um gerente. Utilize instanceof.
import java.util.*;
public class TestaEmpregadoGerente
{ public static void main (String[] args)
{ Gerente mandaChuva =
new Gerente ("Ricardo Silva", 7500,
new GregorianCalendar(1987, 12, 15));
// Cadastramos 3 empregados:
Empregado[] vetEmpregados = new Empregado[3];
vetEmpregados [0] = mandaChuva;
vetEmpregados [1] =
new Empregado ("Claudia Lins", 2000,
new GregorianCalendar (1992, 12, 6));
vetEmpregados [2] =
new Empregado ("Luciana Arruda", 2500,
new GregorianCalendar (1993, 1, 12));
mandaChuva.setSecretaria(vetEmpregados[1]);
System.out.println ("Relao de Empregados e suas Secretrias");
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 105
Classes do tipo Abstract
A medida que voc sobe na hierarquia de herana de uma famlia de classes, as classes se
tornam mais gerais e provavelmente mais abstratas. Em algum ponto uma classe ancestral
se torna to geral que passa a fazer parte apenas da hierarquia para outras classes. Estas
classes (muito gerais) no possuem instncias especficas que voc desejaria utilizar.
Considere, por exemplo, um sistema de mensagens eletrnicas que integre e-mails,
mensagens por fax e mensagens por voz. Naturalmente uma caixa de correio necessita
armazenar uma mistura destes trs tipos de mensagens, logo as mensagens devero ser
acessadas atravs de referncias classe pai comum denominada Mensagem.
Mensagem
MensagemTexto
MensagemVoz
Definir a classe Mensagem faz com que o projeto das suas classes mais limpo. Neste
caso, todas as mensagens possuem um mtodo comum denominado mostrar(). fcil
imaginar como mostrar uma mensagem de voz basta envi-la para o auto falante. J
uma mensagem no formato texto pode ser mostrada exibindo-a em uma janela de texto.
Mas como implementar o mtodo mostrar() na classe Mensagem? A resposta que no
possvel. Em Java utiliza-se a palavra-chave abstract para indicar que um mtodo no
pode ser especificado nesta classe. Uma classe com um ou mais mtodos definidos como
abstract devem ser declaradas como abstract.
public abstract class Mensagem
{ . . .
public abstract void mostrar();
}
Alm de mtodos do tipo abstract, uma classe abstrata pode possuir dados e mtodos
concretos. Por exemplo, a classe Mensagem pode armazenar o remetente da mensagem e
pode possuir um mtodo concreto que retorne o nome deste remetente.
abstract class Mensagem
{ public Mensagem (String de)
{ remetente = de;
}
public abstract void mostrar();
public String getRemetente()
{ return remetente;
}
private String remetente;
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 106
Um mtodo do tipo abstract promete que todos os descendentes desta classe abstrata iro
implementar este mtodo. Uma classe pode ser declarada como abstrata embora no
possua mtodos abstratos. Uma classe abstrata no pode ser instanciada, isto , no
podem ser criados objetos desta classe. Ser preciso estender (extend) a classe para ser
possvel criar uma instncia da classe. Note que possvel criar variveis de instncia na
classe abstrata, mas estas variveis devem referenciar objetos de uma subclasse no
abstrata.
Exemplo:
Mensagem msg = new MensagemTexto (Bom dia);
Neste exemplo msg uma varivel da classe abstrata Mensagem que se refere a uma
instncia da subclasse no abstrata MensagemTexto.
Para ver um exemplo concreto de utilizao da classe abstrata Mensagem e do mtodo
mostrar, vejamos o cdigo nas prximas 3 pginas.
Note que s foi preciso fornecer uma definio concreta do mtodo mostrar nas classes
MensagemTexto e MensagemVoz. Ao executar o programa abaixo devero ser
fornecidas mensagens escritas e mensagens de voz. Para fornecer uma mensagem de voz
preciso digitar o nome de um arquivo no formato .au. No diretrio da classe
TesteDeCorreio h dois arquivos neste formato que podem ser utilizados para executar o
programa: comehome.au e meeting.au.
No momento no tente entender o cdigo para tocar um arquivo de som e para tratar
excees. Estes assuntos sero examinados mais adiante.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 107
import java.net.*;
import java.applet.*;
import corejava.*;
public class TesteDeCorreio
{ public static void main(String[] args)
{ CaixaDeCorreio umaCaixa = new CaixaDeCorreio();
while (true)
{ System.out.println(umaCaixa.status());
String cmd = Console.readLine ("mostrar, texto, voz, fim> ");
if (cmd.equals("mostrar"))
{ Mensagem m = umaCaixa.remove();
if (m != null)
{ System.out.println("De: " + m.getRemetente());
m.mostrar();
}
}
else if (cmd.equals("texto"))
{ String de = Console.readLine("Seu nome: ");
boolean mais = true;
String msg = "";
System.out.println ("Digite uma mensagem e 'fim' " +
"para encerrar.");
while (mais)
{ String linha = Console.readLine();
if (linha.equals("fim"))
mais = false;
else msg = msg + linha + "\n";
}
umaCaixa.insert(new MensagemTexto(de, msg));
}
else if (cmd.equals("voz"))
{ String de = Console.readLine("Seu nome: ");
String msg
= Console.readLine("Nome do arquivo de Som: ");
umaCaixa.insert(new MensagemVoz(de, msg));
}
else if (cmd.equals("fim"))
System.exit(0);
}
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 108
abstract class Mensagem
{ public Mensagem(String de)
{ remetente = de;
}
public abstract void mostrar();
public String getRemetente()
{ return remetente;
}
private String remetente;
}
class MensagemTexto extends Mensagem
{ public MensagemTexto(String de, String t)
{ super(de);
texto = t;
}
public void mostrar()
{ System.out.println(texto);
}
private String texto;
}
class MensagemVoz extends Mensagem
{ public MensagemVoz(String de, String f)
{ super(de);
nomeDoArquivo = f;
}
public void mostrar()
{ try
{ URL u = new URL("file", "localhost", nomeDoArquivo);
AudioClip clip = Applet.newAudioClip(u);
clip.play();
}
catch(Exception e)
{ System.out.println("Nao pode abrir " + nomeDoArquivo);
}
}
private String nomeDoArquivo;
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 109
class CaixaDeCorreio
{ public Mensagem remove()
{ if (nmsg == 0) return null;
Mensagem r = mensagens[saida]; // Saida indica qual a
// mensagem
nmsg--; // que vai sair. Simula uma lista
saida = (saida + 1) % MAXMSG; // circular.
return r;
}
public void insert(Mensagem m)
{ if (nmsg == MAXMSG) return;
mensagens[entrada] = m; // Entrada indica a posicao onde
nmsg++; // a mensagem vai entrar. Simula
entrada = (entrada + 1) % MAXMSG; // uma lista circular.
}
public String status()
{ if (nmsg == 0) return "Caixa de Correio vazia";
else if (nmsg == 1) return "1 message";
else if (nmsg < MAXMSG) return nmsg + " mensagens";
else return "Caixa de Correio cheia";
}
private final int MAXMSG = 10;
private int entrada = 0;
private int saida = 0;
private int nmsg = 0;
private Mensagem[] mensagens = new Mensagem[MAXMSG];
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 110
Exemplo de Mtodo Abstract
Exerccio: Defina uma classe vendedor com as seguintes caractersticas:
1. A classe Vendedor deve estender Empregado.
2. Deve possuir duas variveis de instncia: percentualDeComissao e vendasNoMes,
ambas do tipo double.
3. Quando um vendedor cadastrado estas informaes devem ser fornecidas.
4. Deve possuir um mtodo aumentaSalario (double
percentualAumento). Sempre que um vendedor recebe um aumento, o
percentual de aumento no incide sobre o salrio e sim sobre o percentual de
comisso.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 111
import java.util.*;
class Gerente extends Empregado
{ public Gerente (String n, double s, GregorianCalendar d)
{ super(n, s, d);
nomeDaSecretaria = " ";
}
public void aumentaSalario (double percentualDeAumento)
{ // adiciona 0,5 % de bonus para cada ano de servio
GregorianCalendar hoje = new GregorianCalendar();
double bonus = 0.5 * (hoje.get(Calendar.YEAR)
anoContratacao());
double novoSalario = super.getSalario() * (1 +
(percentualDeAumento + bonus)/100);
super.setSalario(novoSalario);
}
public String getNomeDaSecretaria()
{ return nomeDaSecretaria;
}
public void setNomeDaSecretaria(String nome)
{ nomeDaSecretaria = nome;
}
private String nomeDaSecretaria;
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 112
import java.util.*;
abstract class Empregado
{ public Empregado (String n, double s, GregorianCalendar d)
{ nome = n;
salario = s;
dataContratacao = d;
}
public void print()
{ System.out.println (nome + " " + salario + " " +
anoContratacao());
}
public abstract void aumentaSalario (double percentualDeAumento);
public void alteraDataContratacao (int ano, int mes, int dia)
{ dataContratacao.set(Calendar.YEAR, ano);
dataContratacao.set(Calendar.MONTH, mes);
dataContratacao.set(Calendar.DATE, dia);
}
public int anoContratacao()
{ return dataContratacao.get(Calendar.YEAR);
}
public String getNome()
{ return nome;
}
public double getSalario()
{ return salario;
}
public void setSalario(double sal)
{ salario = sal;
}
private String nome;
private double salario;
private GregorianCalendar dataContratacao;
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 113
Utilize o programa abaixo para testar o que voc programou.
import java.util.*;
import corejava.*;
public class TestaEmpregadoGerente
{ public static void main (String[] args)
{ Gerente mandaChuva =
new Gerente ("Ricardo Silva", 7500,
new GregorianCalendar(1987, 12, 15));
mandaChuva.setNomeDaSecretaria ("Claudia Lins");
// Cadastramos 3 empregados:
Empregado[] vetEmpregados = new Empregado[2];
vetEmpregados [0] = mandaChuva;
vetEmpregados [1] =
new Vendedor ("Luciana Arruda", 2500,
new GregorianCalendar (1993, 1, 12), 5, 10000);
int i;
System.out.println ("Empregados e Salarios antes do aumento");
for (i = 0; i < 2; i++) vetEmpregados[i].print();
System.out.println ("");
for (i = 0; i < 2; i++) vetEmpregados[i].aumentaSalario(5);
System.out.println ("Empregados e salarios apos o aumento");
for (i = 0; i < 2; i++)
{ System.out.println ("Nome = " + vetEmpregados[i].getNome());
System.out.println ("Salario = " + vetEmpregados[i].getSalario());
}
System.out.println ("");
System.out.println ("A secretaria do departamento se chama " +
mandaChuva.getNomeDaSecretaria());
}
}
Observe que uma classe abstrata pode conter mtodos e variveis no abstratas.
Voc no pode construir uma instncia de uma classe abstract, exceto indiretamente
construindo uma instncia de alguma subclasse dela.
Subclasses de classes abstratas devem prover implementaes para todos os mtodos
abstratos nos seus pais, caso contrrio tambm sero classes abstratas.
Voc pode declarar reference variables do tipo da classe abstact.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 114
Mtodos do Tipo Protected
Como voc j sabe, os campos de instncia de uma classe devem ser declarados como
private e os mtodos so geralmente declarados como public. Qualquer coisa declarada
como private no ser visvel por outras classes e isto tambm vale para subclasses:
uma subclasse no pode acessar os dados privados de sua superclasse.
H, no entanto, situaes em que voc deseja que uma subclasse tenha acesso a um
mtodo ou a um dado da sua classe pai. Neste caso, devemos declarar o mtodo ou a
varivel como protected. Por exemplo, se o objeto dataContratacao da classe Empregado
tivesse sido declarado como protected em vez de private, ento os mtodos da classe
Gerente poderiam acessar este campo diretamente.
Na prtica, evite utilizar atributos protected. Suponha que voc projetou uma classe com
campos protected e que esta classe esteja sendo utilizada por outros programadores. Este
programadores podero derivar classes a partir da sua classe e, ento, podero acessar
diretamente os campos definidos como protected. Voc no poder mudar a
implementao da sua classe sem incomodar os outros programadores. Isto contra o
esprito da OOP, que estimula o encapsulamento.
Mtodos do tipo protected fazem mais sentido. Uma classe pode declarar uma
mtodo como protected se ele difcil de usar (cheio de truques). Protected indica
que a subclasse (que presumivelmente conhece bem os seus ancestrais) pode utilizar o
mtodo, mas outras classes, no. Mais adiante veremos um exemplo deste assunto.
Abaixo segue um resumo dos 4 modificadores de acesso que controlam a visibilidade:
1. Visvel apenas na classe: private.
2. Visvel por todas as classes: public.
3. Visvel no package e por todas as subclasses: protected.
4. Visvel no package: o default quando no se especifica nada.
Object: A Superclasse Csmica.
A classe Object o ltimo ancestral de qualquer classe. Toda classe em java estende a
classe Object, no entanto no preciso escrever:
class Empregado extends Object;
Como toda classe em Java estende a classe Object, importante conhecer os servios
fornecidos pela classe Object. Aqui sero apresentados os servios bsicos.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 115
possvel utilizar uma varivel do tipo Object para fazer referncia a objetos de qualquer
tipo:
Object obj = new Empregado (Vinicius Ribeiro, 3500);
Naturalmente uma varivel do tipo Object somente til como um armazenador genrico
para valores arbitrrios. Para fazer qualquer coisa especfica com um objeto do tipo
Empregado preciso ter conhecimento sobre o tipo original do objeto:
Empregado e = (Empregado) obj;
O mtodo equals da classe Object testa se um objeto igual a outro. Na verdade este
mtodo testa apenas se dois objetos apontam para a mesma rea de memria, o que no
um teste muito til. Se voc deseja testar se dois objetos so iguais preciso redefinir
equals:
class Empregado
{ . . .
public boolean equals (Object obj)
{ if (!(obj instanceof Empregado))
return false;
Empregado b = (Empregado) obj;
return nome.equals (b.nome) &&
salario == b.salario &&
dataContratacao.equals (b.dataContratacao);
}
}
Abaixo vem o cdigo do programa que testa se um objeto qualquer igual a um objeto
Empregado especfico:
import java.util.*;
public class TestaEmpregado
{ public static void main (String[] args)
{ Projeto umProjeto = new Projeto("Bacuri");
Empregado umEmpregado = new Empregado ("Vinicius Aguiar", 4500,
new GregorianCalendar (1992, 6, 13));
Object umObjeto = umEmpregado;
if (umEmpregado.equals(umObjeto))
System.out.println(" igual");
else
System.out.println("No igual");
umObjeto = umProjeto;
if (umEmpregado.equals(umObjeto))
System.out.println(" igual");
else
System.out.println("No igual");
}
}
Um outro importante mtodo da classe Object o mtodo toString que retorna um string
que representa o valor deste objeto. Quase todas as classes fazem um override deste
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 116
mtodo a fim de lhe dar uma representao impressa do estado corrente do objeto.
Sempre que um objeto concatenado a um string, atravs do operador +, o compilador
Java chama automaticamente o mtodo toString para obter o estado atual do objeto.
GregorianCalendar d = new GregorianCalendar (1999, 12, 31);
String ultimoDia = O ultimo dia do milenio e + d;
// Automaticamente o mtodo toString chamado.
Todos os valores de qualquer tipo de classe podem ser armazenados em variveis do tipo
Object. Por exemplo, valores da classe String so objetos, logo:
Object obj = Oi; // OK
No entanto, nmeros, caracteres e valores boleanos no so objetos, logo:
obj = 5; // Erro!
obj = false; // Erro!
Todos os tipos de arrays so classes que derivam da classe Object.
Empregado[] empregados = new Empregado[10];
Object arr = empregados; // Um array de empregados um
// objeto logo pode ser armazenado em uma varivel do tipo
// Object. No preciso escrever:
// Object [] arr = empregados; Escrevendo desta forma
// dar erro na linha abaixo pois um array de inteiros no
// um array de objetos.
arr = new int[10]; // Um array de inteiros um objeto,
// logo pode ser armazenado em uma
// varivel do tipo Object.
Um array de objetos pode ser convertido para um array de objects. Por exemplo, um array
do tipo Empregado[] pode ser passado para uma funo que espera receber um array
do tipo Object[]. Esta converso til quando se est programando de forma
genrica.
Exemplo:
static int encontrar (Object[] a, Object b)
{ int i;
for (i = 0; i < a.length; i++)
if (a[i].equals(b)) return i;
return 1; // Caso no encontre.
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 117
Cdigo que chama a funo:
Empregado[] empregados = new Empregado[10];
Empregado Silvia;
. . .
int n = encontrar (empregados, silvia);
// Observe que encontrar um mtodo esttico, logo:
// 1. Pertence classe que o est chamando ou
// 2. Pertence a uma classe que contm apenas mtodos
// gerais e estticos.
//
// Veja os exemplos 1 e 2 abaixo.
Exemplo 1: (Mtodo encontrar definido na prpria classe)
import java.util.*;
public class TestaEmpregado
{ public static void main (String[] args)
{ // Projeto umProjeto = new Projeto("Bacuri");
Empregado [] empregados = new Empregado[2];
Empregado vinicius = new Empregado ("Vinicius Aguiar", 4500,
new GregorianCalendar (1992, 6, 13));
Empregado carlos = new Empregado ("Carlos Ribeiro", 5500,
new GregorianCalendar (1993, 7, 14));
empregados[0] = carlos;
empregados[1] = vinicius;
int n = encontrar(empregados, carlos);
if (n==-1)
System.out.println("No achou");
else
System.out.println("Achou na posio: " + n);
}
static int encontrar (Object[] a, Object b)
{ int i;
for (i = 0; i < a.length; i++)
if (a[i].equals(b)) return i;
return -1; // Caso no encontre.
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 118
Exemplo 2: (Mtodo encontar definido em outra classe)
import java.util.*;
public class TestaEmpregado
{ public static void main (String[] args)
{ // Projeto umProjeto = new Projeto("Bacuri");
Empregado [] empregados = new Empregado[2];
Empregado vinicius = new Empregado ("Vinicius Aguiar", 4500,
new GregorianCalendar (1990, 5, 26));
Empregado carlos = new Empregado ("Carlos Ribeiro", 5500,
new GregorianCalendar (1993, 7, 14));
empregados[0] = carlos;
empregados[1] = vinicius;
int n = FuncoesGerais.encontrar(empregados, carlos);
if (n==-1)
System.out.println("No achou");
else
System.out.println("Achou na posio: " + n);
}
}
public class FuncoesGerais
{ static int encontrar (Object[] a, Object b)
{ int i;
for (i = 0; i < a.length; i++)
if (a[i].equals(b)) return i;
return -1; // Caso no encontre.
}
}
Note que voc s pode converter um array de objetos em um array do tipo Objects. No
possvel converter um array de inteiros (int[]) em um array do tipo Object[], uma
vez que int[] um objeto mas no um array de objetos. No entanto, como j vimos,
tanto o array de inteiros quanto um array de objetos pode ser armazenado em uma
varivel do tipo Object.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 119
Se voc converter um array de objetos em um array do tipo Objects[], o array genrico
ainda se lembra, em tempo de execuo, do seu tipo original.
import java.util.*;
public class TestaEmpregado
{ public static void main (String[] args)
{ Empregado[] empregados = new Empregado[10];
Object[] arr = empregados;
Projeto proj = new Projeto("Bacuri");
Empregado aaa =
new Empregado ("Vinicius Aguiar", 4500,
new GregorianCalendar (1992, 6, 13));
arr[0] = aaa;
arr[1] = proj;
}
}
O comando arr[1] = proj provoca um erro pois arr aponta para um vetor de
Empregados, e proj do tipo Projeto.
possvel armazenar objetos de classes diferentes em um vetor de Objects. No exemplo
abaixo, por exemplo, para recuperar a informao e mandar executar um mtodo
preciso efetuar o cast uma vez que a classe Object no implementa o mtodo
aumentaSalario, nem mesmo como abstract.
import java.util.*;
import java.applet.*;
public class TestaEmpregado
{ public static void main (String[] args)
{ Empregado emp = new Empregado ("Luis Claudio", 3500,
new GregorianCalendar (1989, 10, 1));
Projeto proj = new Projeto("Bacuri");
Object[] arr = new Object[10];
arr[0] = emp;
arr[1] = proj;
// O comando abaixo retorna uma exceo quando
// acessa empregados[1] que no aponta para um
// empregado.
for (int i = 0; i < 2; i++)
if (arr[i] instanceof Empregado)
((Empregado)arr[i]).aumentaSalario(3);
};
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 120
java.lang.object
Class getClass()
Retorna um objeto do tipo Class que contm informaes sobre o objeto.
Boolean equals(Object obj)
Compara dois objetos. Verifica se os dois objetos apontam apara a mesma regio de
memria.
Object clone()
Cria um clone de um objeto. O run-time aloca memria para a nova instncia do
objeto e copia a memria alocada para o objeto corrente.
String toString
Retorna um string que representa a descrio do objeto.
Vectors
Em Java possvel definir o tamanho de um array em tempo de execuo.
int n;
. . .
Item[] itensPedidos = new Item[n + 1];
Este cdigo no resolve completamente o problema. Com ele pode-se definir o tamanho
de um array em tempo de execuo, mas uma vez definido este tamanho, no se pode
modific-lo facilmente.
H em Java um objeto que trabalha de forma similar a um array e que pode encolher e
crescer ao longo da execuo de um programa. Este objeto se chama Vector.
H uma importante diferena entre um Vector e um array. Arrays so implementados
na prpria linguagem Java. J o Vector uma classe definida no package java.util.
Este tipo Vector armazena elementos do tipo Object, logo ser preciso utilizar o
cast quando voc desejar extrair um item de um Vector.
Para construir um novo Vector preciso especificar, no construtor do Vector, a sua
dimenso inicial.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 121
Exemplo:
Vector itensPedidos = new Vector(3);
Existe uma importante distino entre a capacidade de um Vector e o tamanho de um
array. Se voc alocar um array com 3 entradas, ento o array possuir 3 entradas e estar
pronto para uso. J um Vector com capacidade para armazenar 3 elementos possui o
potencial para armazenar 3 elementos (e at mais do que 3), mas a princpio, mesmo aps
a sua construo inicial, um Vector no armazena nenhum elemento.
Utilize o mtodo add para adicionar novos elementos a um Vector. Por exemplo,
suponha que voc possui uma classe denominada Item e utiliza o seguinte cdigo para
criar 3 objetos do tipo Item:
Item item1 = new Item( . . . );
Item item2 = new Item( . . . );
Item item3 = new Item( . . . );
Ento, utiliza-se o seguinte cdigo para adicionar estes itens ao Vector itensPedidos:
itensPedidos.add(item1);
itensPedidos.add(item2);
itensPedidos.add(item3);
Se voc inserir um quarto item neste Vector, ser encontrado um local maior para
armazen-lo e as entradas existentes no Vector so automaticamente copiadas para este
novo local. Por default, o novo espao alocado para o Vector dobra o espao
atualmente ocupado. Em funo do problema do crescimento exponencial do espao
alocado, possvel especificar, no construtor, de quanto ser o crescimento do Vector a
cada nova realocao.
Exemplo:
Vector itensPedidos = new Vector (3, 10);
Agora o vector cresce em incrementos de 10 a cada nova realocao. Por outro lado, se
Java precisar realocar o espao ocupado por um Vector com freqncia o desempenho
do programa cair muito, logo tome cuidado quando definir a alocao inicial de um
Vector.
Para pequenos programas pode-se utilizar o construtor default que aloca inicialmente 10
posies para o Vector e dobra o espao ocupado a cada nova realocao:
Vector itensPedidos = new Vector ();
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 122
Trabalhando com um Vector Existente
O mtodo size() retorna o nmero corrente de elementos em um Vector. Logo,
v.size() equivale ao a.length para arrays.
Quando voc estiver certo que o Vector se encontra no seu tamanho permanente, voc
poder chamar o mtodo trimToSize(). Este mtodo ajusta o tamanho do bloco de
memria para utilizar exatamente a quantidade de memria necessria para armazenar o
nmero corrente de elementos no Vector. O coletor de lixo ir recuperar a memria
excedente.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 123
Acessando um Elemento de um Vector
As duas maiores diferenas entre Vectors e arrays so:
1. Em vez de utilizar [] para referenciar os elementos deve-se utilizar os mtodos get e
set.
Arrays Vectors
x = a[i]; x = v.elementAt(i); ou x = v.get(i);
a[i] = x; v.setElementAt(x, i); ou v.set(i, x);
Os mtodos get e set foram adicionados na verso 1.2 do JDK.
Para obter o melhor de ambos os recursos pode-se fazer o seguinte:
Vector v = new Vector();
while ( . . . )
{ String s = . . .
v.add (s);
}
E quando o tamanho do Vector no for mais mudar efetua-se uma cpia dos elementos
do Vector para um array com o mtodo copyInto desenvolvido para este fim:
String[] a = new String[v.size()];
v.copyInto(a);
Ateno, no chame o mtodo v.setElementAt (x, i) enquanto o tamanho (size) do
Vector no for maior do que i.
Exemplo:
Vector v = new Vector(10); // capacidade 10, tamanho zero.
v.set (0, x); // Isto provoca um erro. A posio
// zero ainda no existe.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 124
Existem duas solues para este problema:
a) Utilize o mtodo addElement em vez de setElementAt.
Vector v = new Vector (10);
v.add (0, x); // Adiciona um elemento ao vector e faz
// v.size() ser igual a 1.
b) Chame o mtodo setSize aps criar o vector.
Vector v = new Vector(10); // capacidade 10, tamanho zero.
v.setSize (10); // capacidade 10, tamanho 10.
v.set (0, x); // Isto no provoca um erro.
2. Existe uma nica classe Vector e esta classe armazena elementos de qualquer tipo:
um Vector armazena uma seqncia de objetcs.
Isto no um problema no momento da insero de elementos em um Vector afinal
todas as classes so derivadas da classe Object. Haver um problema no entanto, se voc
desejar construir um Vector de nmeros. Neste caso ser preciso utilizar uma classe
que funcione como um invlucro tais como as classes Integer e Double veja a prxima
sesso. Mas como os itens so armazenados como objects ser preciso utilizar o cast para
recuper-los do Vector.
Exemplo:
Vector itensPedidos = new Vector(10);
itensPedidos.setSize (10);
Item umItem = new Item();
itensPedidos.set (posicao, umItem);
A varivel umItem automaticamente convertida do tipo Item para o tipo Object quando
inserida no Vector. Mas quando voc l umItem de um Vector, voc obtm um
Object e ento preciso converter de volta para o tipo original. Sem esta converso no
possvel trabalhar com o objeto, isto , sem ela o compilador gera uma mensagem de
erro.
Item itemCorrente = (Item) itensPedidos.get(posicao);
Vector so inerentemente pouco seguros. possvel acidentalmente adicionar um
elemento de um tipo errado a um Vector.
Retangulo r = new Retangulo ();
itensPedidos.set(n, r); // Erro!
A atribuio do objeto r ao Vector no o problema. A questo que, posteriormente, ao
se recuperar este objeto armazenado no Vector, provavelmente ser feita a sua
converso (cast) para o tipo Item. Este um problema dos Vectors pois eles armazenam
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 125
valores do tipo Objects. Se itensPedidos fosse um array de valores do tipo Item, ento o
compilador no aceitaria a atribuio de um objeto do tipo Retngulo para o array.
Item[] itensPedidos = new Item[3];
Retangulo r = new Retangulo();
itensPedidos[1] = r; // Erro!
Na prtica, no entanto, geralmente possvel garantir que os elementos inseridos em um
Vector possuem o tipo desejado. Veja o cdigo abaixo:
class Pedido
{ . . .
public void adicionarItem (Item i)
{ itensPedidos.add(i);
}
. . .
private Vector itensPedidos;
}
O Vector itensPedidos um campo private da classe Pedido e o nico mtodo que
adiciona objetos neste Vector Pedido.adicionarItem. Como o argumento de
Pedido.adicionarItem um objeto do tipo Item, somente objetos deste tipo
podem ser adicionados ao Vector. Logo, em tempo de compilao o compilador tem
como verificar o tipo do objeto que se pretende acrescentar ao Vector.
Pedido.adicionarItem(new Retangulo()); // Resultar em um erro!
Assim poderemos, com segurana, recuperar objetos do Vector e convert-los em Item.
Em ocasies raras Vectors so teis para armazenar colees heterogneas. Objetos de
classes completamente diferentes podem ser inseridos em um Vector. Neste caso,
quando uma entrada no Vector recuperada preciso testar o tipo do objeto
recuperado, conforme vem no cdigo abaixo:
Vector pedidoDeCompra;
pedidoDeCompra.add(new Nome( . . . ));
pedidoDeCompra.add(new Endereco( . . . ));
pedidoDeCompra.add(new Item( . . . ));
. . .
Object obj = pedidoDeCompra.get(n);
if (obj instanceof Item)
{ Item i = (Item) obj;
sum += i.preco();
}
Na verdade, esta no uma boa forma de se escrever cdigo. No se deve jogar fora o
tipo de uma dado para depois tentar recuper-lo programaticamente.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 126
Inserindo e Removendo Elementos de um Vector
possvel inserir elementos no meio de um Vector:
int n = itensPedidos.size() 2;
itensPedidos.add(n, proximoItem);
Os elementos localizados nas posies >= n so movidos para cima de forma a abrir
espao para o novo elemento.
Da mesma forma, possvel remover um elemento localizado no meio de um Vector.
Item i = (Item) itensPedidos.remove(n);
Os elementos localizados acima desta posio so copiados para baixo e o tamanho do
vector reduzido em um.
A insero e a remoo de elementos em um Vector no muito eficiente, logo, se
voc necessita armazenar muitos elementos e, com freqncia, precisa acrescentar e
remover elementos no meio do Vector, considere a utilizao de uma lista encadeada.
No faz parte do escopo desta apostila tratar listas encadeadas.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 127
Desempenho: Vectors x Arrays
A alocao de um Vector bem como o acesso a um elemento de um Vector
significativamente mais lento do que a alocao e o acesso a um elemento de um array.
H duas razes para isto:
1. Leva mais tempo chamar um mtodo do que acessar um array diretamente.
2. Alem disso, os mtodos de Vectors so sincronizados. Quando duas threads
acessam o mesmo Vector ao mesmo tempo, as chamadas aos mtodos so
enfileiradas para que apenas uma thread mexa no Vector de cada vez. Esta
sincronizao das threads provoca uma queda no desempenho.
No entanto, a utilizao de Vectors bastante conveniente: crescem dinamicamente,
fornecem a distino entre tamanho e capacidade e so teis em programas que trabalham
com vrias threads. Recomenda-se a utilizao de Vectors quando se pretende
trabalhar com pequenos conjuntos de dados de tamanho varivel.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 128
Exemplo de um programa para controlar os empregados lotados em determinado
departamento utilizando Vector.
Programa Principal:
import java.util.*;
public class TestaEmpregado
{ public static void main (String[] args)
{ Departamento umDepartamento = new Departamento ("Compras");
Empregado vinicius = new Empregado ("Vinicius Aguiar", 4500,
new GregorianCalendar (1992, 6, 13));
umDepartamento.adicionarEmpregado(vinicius);
Empregado carlos = new Empregado ("Carlos Ribeiro", 5500,
new GregorianCalendar (1993, 7, 14));
umDepartamento.adicionarEmpregado(carlos);
Empregado luiz = new Empregado ("Luiz Carlos", 6500,
new GregorianCalendar (1995, 11, 12));
umDepartamento.adicionarEmpregado(luiz);
System.out.println ("Lista de Empregados");
umDepartamento.listarEmpregados();
Empregado empRemovido = umDepartamento.removerEmpregado(carlos);
if (!(empRemovido == null))
System.out.println ("Nome do Empregado removido = " +
empRemovido.getNome());
else
System.out.println ("Empregado Inexistente. Nome = "
+ carlos.getNome());
System.out.println ("Lista de Empregados");
umDepartamento.listarEmpregados();
empRemovido = umDepartamento.removerEmpregado(carlos);
if (!(empRemovido == null))
System.out.println ("Nome do Empregado removido = " +
empRemovido.getNome());
else
System.out.println ("Empregado Inexistente. Nome = "
+ carlos.getNome());
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 129
Classe Empregado:
import java.util.Calendar;
class Empregado
{ public Empregado (String n, double s, GregorianCalendar d)
{ nome = n;
salario = s;
dataContratacao = d;
}
public boolean equals (Object obj)
{ if (!(obj instanceof Empregado))
return false;
Empregado b = (Empregado) obj;
return nome.equals (b.nome)
&& salario == b.salario
&& dataContratacao.equals (b.dataContratacao);
}
public void print()
{ System.out.println (nome + " " + salario + " " +
anoContratacao());
}
public void aumentaSalario (double percentualDeAumento)
{ salario = salario * (1 + percentualDeAumento) / 100;
}
public void alteraDataContratacao (int ano, int mes, int dia)
{ dataContratacao.set(Calendar.YEAR, ano);
dataContratacao.set(Calendar.MONTH, mes);
dataContratacao.set(Calendar.DATE, dia);
}
public int anoContratacao()
{ return dataContratacao.get(Calendar.YEAR);
}
public String getNome()
{ return nome;
}
private String nome;
private double salario;
private GregorianCalendar dataContratacao;
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 130
Classe Departamento:
import java.util.*;
class Departamento
{ public Departamento (String n)
{ nome = n;
}
public void print()
{ System.out.println (nome);
}
public void adicionarEmpregado (Empregado e)
{ empregados.add(e);
}
public Empregado removerEmpregado (Empregado e)
{ int n = encontrar (empregados, e);
if (n==-1)
return null;
else
return (Empregado)empregados.remove(n);
}
public void listarEmpregados ()
{ for (int i = 0; i < empregados.size(); i++)
System.out.println
(((Empregado)empregados.get(i)).getNome());
}
private static int encontrar (Vector v, Empregado b)
{ int i;
for (i = 0; i < v.size(); i++)
if (((Empregado)v.get(i)).equals(b)) return i;
return -1; // Caso no encontre.
}
private String nome;
private Vector empregados = new Vector(10);
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 131
Objetos Empacotadores
Ocasionalmente preciso converter um tipo bsico como int para um objeto. Todos os
tipos bsicos possuem classes respectivas. Por exemplo, existe uma classe Integer
correspondente ao tipo bsico int. Estes tipos de classes so geralmente denominadas
Object Wrappers (Objetos Empacotadores).
Estas classes so: Integer, Long, Float, Double, Byte, Character e
Boolean. As primeiras 5 so especializaes da classe pai Number. Todas estas classes
so do tipo final, logo no possvel, por exemplo, fazer o override do mtodo
toString da classe Integer para exibir o nmero em algarismos Romanos. Tambm
no possvel modificar os valores que voc armazena em um objeto destas classes.
Suponha que desejamos um Vector de nmeros do tipo double. Como dissemos
anteriormente no possvel adicionar um nmero a um Vector, uma vez que um
nmero no pertence classe Object.
Vector v = new Vector();
v.add(3.14); // Erro!
Seria preciso utilizar a classe Double:
v.add(new Double(3.14));
E para recuperar um nmero armazenado em um Vector de objetos do tipo Double
seria preciso extrair o valor utilizando o mtodo doubleValue() da classe Double.
double x = ((Double) v.get(n)).doubleValue();
Cuidado: wrapper classes no podem ser utilizadas para implementar mtodos que
modifiquem argumentos numricos. Lembre-se que no possvel escrever uma funo
que incremente um nmero inteiro uma vez que os argumentos dos mtodos so sempre
passados por valor.
static void incrementa (int x) // No vai funcionar.
{ x++; // Incrementa uma cpia local.
}
static void main (String[] args)
{ int a = 3;
incrementa (a);
. . .
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 132
Modificar o valor de x em incrementa no tem nenhum efeito sobre a varivel a. E se
utilizarmos a classe Integer em vez de int?
static void incrementa (Integer x) // No vai funcionar.
{ . . .
}
static void main (String[] args)
{ Integer a = new Integer(3);
incrementa (a);
. . .
}
Aparentemente deveria funcionar uma vez que, agora a e x so referncias ao mesmo
objeto. Ao atualizarmos x, a deveria tambm ser atualizado. O problema que objetos da
classe Integer so imutveis: a informao contida em uma classe wrapper no pode ser
modificada. No existe, por exemplo, um mtodo anlogo a x++ para os objetos da classe
Integer. Logo, no possvel utilizar classes do tipo wrapper para criar um mtodo que
modifique argumentos numricos.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 133
Convertendo Strings em Nmeros
Freqentemente voc ver as classes do tipo wrappers sendo utilizadas por outra razo:
int x = Integer.parseInt(s);
Isto no tem nada a ver com objetos do tipo Integer parseInt um mtodo
esttico. Mas os projetistas de Java acharam que a classe Integer era um bom local
para colocar isso.
At a verso 1.2 no havia o correspondente parseDouble na classe Double. Para
obter o mesmo efeito preciso fazer o seguinte:
double x = new Double(s).doubleValue();
O que isto faz:
1. Utiliza um construtor da classe Double que aceita um string de dgitos na forma de
um double e lhe retorna um objeto do tipo Double.
2. Utiliza o mtodo doubleValue da classe Double que retorna o valor
correspondente do tipo double.
Na prtica, pode ser ainda pior: possvel que o string contenha espaos em branco a
direita ou a esquerda ou pode ainda no conter dgitos, logo, esta converso deveria ser
feita assim:
x = new Double(s.trim()).doubleValue();
Existe um outro mtodo para converter nmeros. Voc pode utilizar o mtodo parse da
classe DecimalFormat. Supondo s um string e df um objeto do tipo
DecimalFormat, ento a chamada ao mtodo df.parse(s) retorna um objeto do
tipo Number.
DecimalFormat df = new DecimalFormat(); // Utiliza o
// default locale
Number n = df.parse(s);
Number uma classe do tipo abstract e o objeto retornado do tipo Long ou do tipo
Double, dependendo do contedo do string s. Voc pode utilizar o operador
instanceof para descobrir o tipo do objeto retornado.
if (n instanceof Double)
Double d = (Double) n;
Mas na prtica, geralmente no estamos ligando para o tipo do objeto retornado. O
mtodo doubleValue encontra-se definido na classe Number e retorna o um nmero
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 134
ponto-flutuante equivalente ao objeto number, independente de se tratar de um Long
ou um Double.
Exemplo:
try
{ x = new DecimalFormat().parse(s.trim()).doubleValue();
}
catch(ParseException e)
{ x = 0;
}
H uma vantagem na utilizao de DecimalFormat: o string pode conter separadores
de milhar e de casas decimais tal como: 12,301.40.
A Classe Class (Identificao de Tipo em Tempo de Execuo)
Enquanto o seu programa est executando o Java run-time System sempre mantm o
run-time type identification de todos os objetos. Com estas informaes o interpretador
Java consegue saber a que classe cada objeto pertence. Assim, em tempo de execuo
esta informao utilizada para que o interpretador possa selecionar corretamente que
mtodo deve ser executado.
No entanto, possvel acessar esta informao trabalhando com uma classe especial
denominada Class. O mtodo getClass da classe Object retorna uma instncia do tipo
Class.
Exemplo:
Empregado e;
. . .
Class c1 = e.getClass();
Provavelmente o mtodo mais comumente utilizado da classe Class o getName. Este
mtodo retorna o nome da classe. Voc pode utiliz-lo, por exemplo, para imprimir o
nome da classe:
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 135
Exemplo:
import java.util.*;
public class ImprimeClasse
{ public static void main (String[] args)
{ Gerente mandaChuva =
new Gerente ("Ricardo Silva", 7500,
new GregorianCalendar(1987, 12, 15));
mandaChuva.setNomeDaSecretaria ("Claudia Lins");
// Cadastramos 3 empregados:
Empregado[] vetEmpregados = new Empregado[3];
vetEmpregados [0] = mandaChuva;
vetEmpregados [1] =
new Empregado ("Claudia Lins", 2000,
new GregorianCalendar (1992, 12, 6));
vetEmpregados [2] =
new Empregado ("Luciana Arruda", 2500,
new GregorianCalendar (1993, 1, 12));
int i;
System.out.println ("Classe a que Cada Empregados Pertence");
System.out.println ("");
for (i = 0; i < 3; i++)
System.out.println (vetEmpregados[i].getClass().getName() +
" " + vetEmpregados[i].getNome());
}
}
Observaes:
vetEmpregados[i].getClass(); // retorna um objeto do tipo Class.
vetEmpregados[i].getClass().getName(); // retorna o nome da classe.
vetEmpregados[i].getNome(); // retorna o nome do empregado.
Este cdigo imprimir:
Classe a que Cada Empregados Pertence
Gerente Ricardo Silva
Empregado Claudia Lins
Empregado Luciana Arruda
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 136
Pode-se obter um objeto do tipo Class de trs formas:
Recuperando-se o objeto tipo Class de um determinado objeto.
vetEmpregados[i].getClass(); // retorna um objeto do tipo Class.
Fornecendo-se um string para o mtodo forName da classe Class que retorna um
objeto tipo Class relativo ao string fornecido.
try
{ c1 = Class.forName("Gerente");
}
catch(Exception e)
{ System.out.println("Deu erro!");
}
System.out.println (c1.getName() + " " + vetEmpregados[i].getNome());
Esta forma seria utilizada quando o nome da classe armazenado em um string que
varia em tempo de execuo.
Supondo T um tipo Java, ento T.class retorna o objeto Class correspondente.
Class cl1 = Gerente.class;
Class cl2 = int.class;
Class cl3 = Double[].class;
Note que Class realmente descreve um tipo que pode ou no ser uma classe.
Um outro exemplo de mtodo til um que nos permite criar uma instncia de uma
classe facilmente. Este mtodo denomina-se newInstance().
Exemplo:
e.getClass().newInstance();
O cdigo acima cria uma nova instncia da mesma classe de e. O mtodo newInstance
chama o construtor default (aquele que no possui argumentos) para inicializar o objeto
recm criado.
Utilizando uma combinao de forName e de newInstance possvel criar um objeto de
uma classe cujo nome encontra-se armazenado em um string.
String s = Gerente;
Object m = Class.forName(s).newInstance();
Se voc necessitar fornecer parmetros para o construtor de uma classe que voc deseja
criar a partir do nome da classe, no ser possvel utilizar os comandos especificados
acima. Ser preciso utilizar o mtodo newInstance da classe Constructor. Esta uma das
vrias classes existentes no package java.lang.reflect.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 137
INTERFACES E INNER CLASSES
J estudamos todas as ferramentas bsicas para desenvolver programas orientados a
objetos em Java. Este captulo mostra duas tcnicas avanadas um pouco mais
complexas:
A primeira, denominada Interface, a maneira de Java fazer com que uma classe tenha o
comportamento de dois ou mais pais. Isto geralmente conhecido como herana
mltipla.
E a segunda tcnica trata das Inner Classes que so mais uma convenincia do que uma
necessidade. Inner classes so importantes para se escrever cdigo conciso e profissional
para manipular eventos provenientes de uma interface grfica.
Interfaces
Utilizando uma Superclasse do tipo Abstract
Suponha que desejamos escrever um cdigo genrico de ordenao que funcionasse em
diferentes tipos de objetos Java. Comeamos com uma classe abstract denominada
Sortable com um mtodo denominado compareTo que determina se um objeto
menor, maior ou igual a outro.
Abaixo vem um algoritmo de ordenao genrico (ArrayAlg) capaz de ordenar objetos do
tipo Sortable. No se preocupe com o funcionamento interno deste algoritmo. Apenas
observe que o algoritmo trabalha com array de elementos, os compara e os rearruma.
Este algoritmo poder ser utilizado com todas as subclasses da classe abstrata
Sortable, atravs de um override do mtodo compareTo na subclasse.
Por exemplo, para ordenar um array de empregados pelo salrio preciso:
a) Derivar Empregado de Sortable.
b) Implementar o mtodo compareTo para empregados.
c) Chamar ArrayAlg.ordena fornecendo o array de empregados.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 138
Exemplo:
import java.util.*;
public class TestaOrdenacaoDeEmpregados
{ public static void main(String[] args)
{ Empregado[] vetEmpregados = new Empregado[3];
vetEmpregados [0] =
new Empregado ("Ricardo Silva", 35000,
new GregorianCalendar(1989,10,1));
vetEmpregados[1] =
new Empregado ("Claudia Lins", 75000,
new GregorianCalendar(1987,10,1));
vetEmpregados [2] =
new Empregado ("Luciana Arruda", 38000,
new GregorianCalendar(1990,3,15));
ArrayAlg.ordena(vetEmpregados);
int i;
for (i = 0; i < vetEmpregados.length; i++)
System.out.println(vetEmpregados [i]);
}
}
abstract class Sortable
{ public abstract int compareTo(Sortable b);
}
class ArrayAlg
{ public static void ordena(Sortable[] a)
{ int n = a.length;
boolean troca = true;
while (troca)
{ troca = false;
for (int i = 0; i < n - 1; i++)
{ Sortable temp = a[i];
if (temp.compareTo(a[i+1]) > 0)
{ a[i] = a[i + 1];
a[i + 1] = temp;
troca = true;
}
}
}
}
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 139
class Empregado extends Sortable
{ public Empregado (String n, double s, GregorianCalendar d)
{ nome = n;
salario = s;
dataContratacao = d;
}
public void aumentaSalario (double percentualDeAumento)
{ salario = salario * (1 + percentualDeAumento/100);
}
public String getNome()
{ return nome;
}
public double getSalario()
{ return salario;
}
public String toString()
{ return nome + " " + salario + " " + anoContratacao();
}
public int anoContratacao()
{ return dataContratacao.getYear();
}
public int compareTo(Sortable b)
{ Empregado eb = (Empregado)b;
if (salario < eb.salario) return -1;
if (salario > eb.salario) return 1;
return 0;
}
private String nome;
private double salario;
private GregorianCalendar dataContratacao;
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 140
Utilizando uma Interface
Infelizmente h um problema na utilizao de uma classe abstrata base para expressar
uma propriedade genrica.
O problema que em Java uma classe pode possuir apenas uma superclasse. Para
resolver este problema Java introduz a idia de interfaces para prover grande parte da
funcionalidade que a herana mltipla nos fornece. Os projetistas de Java escolheram este
caminho pois a herana mltipla ou torna os compiladores muito complexos (como em
C++) ou muito ineficientes (como em Eiffel).
Ento o que uma interface? um compromisso de que a sua classe ir implementar
certos mtodos com determinadas assinaturas. Voc inclusive utiliza a palavra-chave
implements para indicar que a sua classe ir manter este compromisso.
Por exemplo:
public interface Comparable
{ public int compareTo (Object b);
}
O cdigo acima indica que qualquer classe que implemente a interface Comparable
ter o mtodo compareTo. Naturalmente, a forma como o mtodo compareTo
funciona em uma classe especfica depende da classe que est implementando a interface
Comparable. A questo que qualquer classe pode assumir o compromisso de
implementar Comparable independentemente da sua superclasse assumir ou no
este mesmo compromisso. Todos os descendentes desta classe automaticamente
implementariam Comparable, e assim todos eles teriam acesso a um mtodo
compareTo com a correta assinatura.
Para dizer a Java que a sua classe implementa Comparable, preciso escrever a
seguinte definio:
class Empregado implements Comparable
Obs.: A interface Comparable deve estar definida em um arquivo .java separado.
Ento, tudo o que voc precisa fazer implementar o mtodo compareTo dentro da classe
Empregado.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 141
Exemplo:
import java.util.*;
public class TestaOrdenacaoDeEmpregados
{ public static void main(String[] args)
{ Empregado[] vetEmpregados = new Empregado[3];
vetEmpregados [0] =
new Empregado ("Ricardo Silva", 35000,
new GregorianCalendar(1989,10,1));
vetEmpregados[1] =
new Empregado ("Claudia Lins", 75000,
new GregorianCalendar(1987,10,1));
vetEmpregados [2] =
new Empregado ("Luciana Arruda", 38000,
new GregorianCalendar(1990,3,15));
ArrayAlg.ordena(vetEmpregados);
int i;
for (i = 0; i < vetEmpregados.length; i++)
System.out.println(vetEmpregados [i]);
}
}
class ArrayAlg
{ public static void ordena(Comparable[] a)
{ int n = a.length;
boolean troca = true;
while (troca)
{ troca = false;
for (int i = 0; i < n - 1; i++)
{ Comparable temp = a[i];
if (temp.compareTo(a[i+1]) > 0)
{ a[i] = a[i + 1];
a[i + 1] = temp;
troca = true;
}
}
}
}
}
Obs.: Observe que a interface abaixo j se encontra definida em
java.lang.Comparable, logo bastaria importar esta classe assim:
import java.lang.Comparable;
public interface Comparable
{ public int compareTo(Object b);
}

_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 142
class Empregado implements Comparable
{ public Empregado (String n, double s, GregorianCalendar d)
{ nome = n;
salario = s;
dataContratacao = d;
}
public void aumentaSalario (double percentualDeAumento)
{ salario = salario * (1 + percentualDeAumento/100);
}
public String getNome()
{ return nome;
}
public double getSalario()
{ return salario;
}
public String toString()
{ return nome + " " + salario + " " + anoContratacao();
}
public void alteraDataContratacao (int ano, int mes, int dia)
{ dataContratacao.set(Calendar.YEAR, ano);
dataContratacao.set(Calendar.MONTH, mes);
dataContratacao.set(Calendar.DATE, dia);
}
public int anoContratacao()
{ return dataContratacao.get(Calendar.YEAR);
}
public int compareTo(Object b)
{ Empregado eb = (Empregado)b;
if (salario < eb.salario) return -1;
if (salario > eb.salario) return 1;
return 0;
}
private String nome;
private double salario;
private GregorianCalendar dataContratacao;
}
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 143
Observe que se a classe pai j implementa uma interface, a sua subclasse no
necessita explicitamente utilizar a palavra-chave implements.
java.lang.Comparable
java.util.Arrays
Propriedades das Interfaces
Embora interfaces no sejam instanciadas com new, elas possuem certas propriedades
similares s classes normais.
Uma vez definida uma interface, pode-se declarar uma varivel objeto com o mesmo
tipo da interface.
Comparable x = new Empregado ( . . . );
Empregado y = new Empregado ( . . . );
if (y.compareTo(x) < 0) . . .
Como voc pode ver sempre possvel designar uma varivel objeto de um tipo que
implementa uma interface - new Empregado ( . . . ) - a uma varivel
objeto declarada com mesmo tipo da interface - x. como se a interface fosse uma
superclasse da classe que implementa a interface.
Da mesma forma como voc utiliza instaceof para verificar se um objeto possui um
determinado tipo, possvel utilizar instanceof para verificar se um objeto pertence a
uma classe que implementa a interface:
if (umObjeto instanceof Comparable) { . . . }
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 144
Na impede que voc estenda uma interface para criar outra. Isto permite a criao de
uma cadeia de interfaces que possuam desde um maior grau de generalidade at um
alto grau de especializao.
Exemplo: Suponha que voc possui uma interface denominada Xxxxx.
public interface Xxxxx
{ public void umMetodo(double x, double y);
}
Ento poderamos imaginar uma interface denominada Powered que a estende:
public interface Yyyyy extends Xxxxx
{ public String outroMetodo();
}
Embora no seja possvel por um campo de instncia ou um mtodo esttico em uma
interface, possvel definir constantes.
Exemplo:
public interface Yyyyy extends Xxxxx
{ public String outroMetodo(Kkkkk);
public static final int CONSTANTE = 95;
}
Uma classe pode implementar vrias interfaces. Isto nos d grande flexibilidade na
definio do comportamento de uma classe. Por exemplo, Java possui uma importante
interface denominada Cloneable. Se a sua classe implementa Cloneable, o mtodo
clone da classe Object far uma cpia dos objetos da sua classe. Suponha, no entanto
que voc deseje poder clonar e comparar objetos. Neste caso voc dever
implementar ambas as interfaces.
Exemplo:
public Gerente extends Empregado implements Cloneable, Comparable
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 145
A Interface Cloneable
Quando efetuamos uma cpia de uma varivel, a varivel original e a cpia so
referncias para o mesmo objeto. Isto significa que uma modificao efetuada em
qualquer objeto tambm afeta o outro.
GregorianCalendar bday = new GregorianCalendar(1959, 6, 16);
GregorianCalendar d = bday;
d.set(Calendar.YEAR, 1970); // Tambm afeta bday.
Se voc quiser que d seja um novo objeto que comece a sua vida igual a bday mas cujo
estado possa divergir ao longo do tempo, ento utilize o mtodo clone().
GregorianCalendar bday = new GregorianCalendar(1959, 6, 16);
GregorianCalendar d = (GregorianCalendar)bday.clone();
// preciso efetuar o cast uma
// vez que clone retorna um objeto.
d.set(Calendar.YEAR, 1970); // No afeta bday.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 146
No entanto, se voc possui uma classe que representa objetos nicos como empregados
em uma companhia, a operao de clone sobre objetos desta classe no faz sentido. Como
os mtodos da classe Object so herdados por todas as classes (inclusive o mtodo
clone() que um mtodo protected da classe Object), Java acrescenta um novo requisito
para que uma classe possa ser clonada esta classe necessita implementar a interface
cloneable para indicar que a clonagem vlida. Concluindo, se voc deseja clonar um
objeto, no basta simplesmente chamar o mtodo clone() sobre este objeto. preciso que
a classe deste objeto implemente a interface Cloneable.
J a classe GregorianCalendar, por exemplo, no representa objetos nicos e portanto
pode ser clonada.
Logo, apenas a prpria classe pode clonar objetos dela prpria, e existe uma razo para
isto. A classe Object implementa o mtodo clone() efetuando cpia bit a bit, uma vez que
ela no conhece nada sobre o objeto que est clonando. Se todos os campos do objeto que
est sendo clonado so nmeros ou outro tipo bsico, a cpia bit a bit funciona bem. Mas
se o objeto contm referncias a outros objetos em um ou mais de seus campos, ento
uma cpia bit a bit contm cpia exata dos campos que contm referncias, logo o objeto
original e o objeto clonado ainda compartilham alguma informao. Veja a figura abaixo:
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 147
responsabilidade do projetista decidir se:
a) O mtodo clone default (da classe Object) bom o suficiente.
b) O mtodo clone default pode ser remendado de forma a ser chamado para variveis
de instncia que possuem referncia a objetos.
c) A situao no tem soluo e o mtodo clone no deve ser chamado.
A terceira opo o default. Para se optar pela primeira ou segunda opo preciso:
a) Implementar a interface Cloneable e
b) Redefinir o mtodo clone, com um access modifier do tipo public.
O usurio de um mtodo clone() pblico ainda assim deve efetuar um cast do
resultado. O mtodo clone() sempre retorna um objeto do tipo Object.
Neste caso o uso da interface Cloneable no tem nada a ver com o uso normal de
interfaces. A interface meramente serve como um indicador (tag) de que o projetista da
classe que est sendo clonada sabe o que est fazendo. A classe Object to paranica
com clonagens que seu mtodo clone() gera uma exceo de run-time se um objeto
requisita uma clonagem sem implementar a interface.
Lembre-se que o objetivo normal de um interface (tal como a interface Comparable)
garantir que a classe implementa um mtodo em particular ou um conjunto de mtodos
especificados na interface. J uma interface do tipo tag no possui mtodos que devam
ser reimplementados pelas classes que a utilizam (implementam). Seu nico objetivo
permitir que voc utilize instanceof para descobrir se um objeto pertence a uma classe
que implementa determinada interface.
if (obj instanceof Cloneable) . . .
Como a interface Cloneable do tipo tag ela no possui mtodos que devam ser
reimplementados pelas classes que a utilizam (implementam).
A seguir vem o que a classe Empregado deveria fazer para redefinir clone():
a) Chamar o mtodo clone de Object para realizar uma cpia bit a bit.
b) Fazer o cast do resultado para Empregado para que possamos modificar o campo de
instncia dataContratacao para que ele seja um clone do objeto GregorianCalendar
original.
c) Retornar o resultado.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 148
Exemplo:
public class Empregado implements Cloneable
{ . . .
public Object clone() // Redefinido como public
{ try
{ Empregado e = (Empregado) super.clone();
e.dataContratacao =
(GregorianCalendar)dataContratacao.clone();
// A classe GregorianCalendar implementa Cloneable
return e;
}
catch (CloneNotSupportedException e)
{ // Isto no deveria acontecer uma vez que objetos do
// tipo Empregado podem ser clonados
return null;
}
}
}
Como voc pode ver a clonagem um assunto delicado, e faz sentido que o mtodo clone
seja definido como protected na classe Object.
_______________________________________________________________________________________
_______________________________________________________________________________________
Apostila de Java Introduo 149
BIBLIOGRAFIA
Cay S. HorstMann e Gray Cornell, Core Java Volume I - Fundamentals, Sun
Microsystems, 1999

Das könnte Ihnen auch gefallen