Вы находитесь на странице: 1из 155

UNIVERSIDADE DE SO PAULO

INSTITUTO DE MATEMTICA E ESTATSTICA


Departamento de Cincia da Computao

Introduo Cincia da Computao


com Java e Orientao a Objetos
Fabio Kon
Alfredo Goldman
Paulo J. Silva e Silva
Editado e Revisado por:
Raphael Y. de Camargo

So Paulo, 11 de fevereiro de 2004

Sugestes e Correes
Se voc encontrar erros ou tiver sugestes para melhorias neste
livro, favor enviar para o email rcamargo@ime.usp.br.

ii

iii

Agradecimentos

Este livro no seria possvel sem a colaborao de inmeros alunos e professores do IME/USP.
Leo Kazuhiro Ueda e Nelson Posse Lago atuaram como assistentes de ensino
na primeira vez em que esta disciplina foi ministrada e foram responsveis por
inmeras contribuies. A aula dirigida do Dr. Java foi preparada pelo Leo.
Fabiano Mitsuo Sato, George Henrique Silva e Igor Ribeiro Sucupira foram
monitores da disciplina tambm em 2003 e colaboraram com alguns exerccios.
Raphael Y. de Camargo realizou um excelente trabalho na edio e reviso do
livro alm de colaborar com alguns exerccios. O Prof. Joo Eduardo Ferreira,
nosso colega no ensino da disciplina de introduo, tm nos dado inmeras
sugestes teis.
Agradecemos ao Prof. Walter Savitch por ter autorizado o uso de sua classe
para entrada de dados.
Finalmente, agradecemos aos alunos de MAC 110 e aos professores que no
foram citados mas que deram sugestes e nos incentivaram a escrever este
livro.

iv

Sumrio
Prefcio

xi

Teatro de Objetos
1.1 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Disputa de Pnaltis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1
1
1

Histria da Computao
2.1 Histria da Computao e Arquitetura do Computador . . . . . . . . . . . . . . . . . . . . .
2.2 E a evoluo do software? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7
7
12

Conversor de Temperaturas
3.1 Analogia entre dramatizao da disputa de pnaltis e Programao Orientada a Objetos . . . .
3.2 Um exemplo real em Java: um conversor para transformar temperaturas de Celsius para Fahrenheit
3.3 Exerccios: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15
15
16
18

Testes Automatizados
4.1 Testes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3 Resolues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

19
19
22
23

Mtodos com vrios parmetros


5.1 Mtodos com vrios parmetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

25
25
28

if else encaixados
6.1 if else encaixados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

31
31
33

Programas com Vrios Objetos


7.1 Programas com Vrios Objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.2 Exerccio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

37
37
39

Laos e Repeties
8.1 Laos em linguagens de programao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.2 O Lao while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

41
41
42

vi

SUMRIO
8.3
8.4

Nmeros primos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Expresses e Variveis Lgicas


9.1 Condies como expresses
9.2 Precedncia . . . . . . . . .
9.3 Exemplos . . . . . . . . . .
9.4 Exerccio: . . . . . . . . . .

44
45

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

49
49
52
52
54

10 Mergulhando no while
10.1 Um pouco mais sobre primos. . . . . .
10.2 Uma biblioteca de funes matemticas.
10.3 do...while . . . . . . . . . . . . . . . .
10.4 Exerccios . . . . . . . . . . . . . . . .

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

57
57
59
60
60

11 Caracteres e cadeias de caracteres


11.1 Um tipo para representar caracteres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11.2 Cadeias de Caracteres (String) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11.3 Exerccios: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

63
63
65
66

12 Manipulando nmeros utilizando diferentes bases


12.1 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

67
68

13 Arrays (vetores)
13.1 Arrays (vetores) . . . . . . . .
13.1.1 O atributo length . .
13.1.2 Inicializao de arrays
13.2 Criao de Programas Java . .
13.3 Exerccios . . . . . . . . . . .

.
.
.
.
.

71
71
73
73
73
75

.
.
.
.

77
77
78
79
79

.
.
.
.

81
81
82
83
85

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

14 for, leitura do teclado e converso de Strings


14.1 O comando for . . . . . . . . . . . . . . .
14.2 Leitura do Teclado . . . . . . . . . . . . .
14.3 Converso de String para nmeros . . . . .
14.4 Exerccios . . . . . . . . . . . . . . . . . .
15 Laos Encaixados e Matrizes
15.1 Laos encaixados . . . . . . . . . .
15.2 Matrizes (arrays multi-dimensionais)
15.3 Exemplo: LIFE, o jogo da vida . . .
15.4 Exerccios . . . . . . . . . . . . . .

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.

.
.
.
.

.
.
.
.

SUMRIO

vii

16 Busca e ordenao
16.1 Busca . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16.2 Pondo ordem na casa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16.3 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

89
89
90
92

17 Busca binria, fuso e o que so as variveis


17.1 Busca binria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17.2 Fuso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17.3 O que guardam as variveis? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

93
93
94
95

18 Construtores e especificadores de acesso


97
18.1 Construtores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
18.2 Especificadores de acesso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
18.3 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
19 Interfaces
19.1 O Conceito de Interfaces . . . . . . . . . . .
19.2 Um primeiro exemplo . . . . . . . . . . . . .
19.3 Implementando mais de uma interface por vez
19.4 Um exemplo mais sofisticado . . . . . . . . .
19.5 Exerccios: . . . . . . . . . . . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

103
103
103
106
108
111

20 Herana
20.1 O Conceito de Herana . . . . . . . . . . . .
20.2 Terminologia de herana . . . . . . . . . . .
20.3 Implementao de herana na linguagem Java
20.4 Hierarquia de Classes . . . . . . . . . . . . .
20.5 Relacionamento um . . . . . . . . . . . .
20.6 Resumo . . . . . . . . . . . . . . . . . . . .
20.7 Exerccios . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

115
115
116
116
118
119
119
119

21 Javadoc
121
21.1 Javadoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
22 O C que h em Java
22.1 O C que h em Java . . . .
22.2 Detalhes de entrada e sada
22.3 Declarao de variveis . .
22.4 Parmetros de funes . .
22.5 Um ltimo exemplo . . . .

.
.
.
.
.

127
127
129
129
130
130

A Utilizando o Dr. Java


A.1 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A.1.1 Como obter, instalar e executar o DrJava . . . . . . . . . . . . . . . . . . . . . . . .
A.2 Conversor de Temperatura simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

133
133
133
134

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

viii

SUMRIO
A.3 Tratando erros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136

Lista de Figuras
2.1
2.2

Arquitetura do ENIAC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Arquitetura de Von Neumann . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

10
10

20.1 Diagrama de herana . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116


20.2 Hierarquia de classes representando os seres vivos . . . . . . . . . . . . . . . . . . . . . . . . 118
20.3 Hierarquia errada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
21.1 Documentao gerada pelo Javadoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125

ix

LISTA DE FIGURAS

Prefcio
Caros alunos e alunas de MAC-110,
Sejam bem-vindos aos maravilhoso mundo da Cincia da Computao. Neste primeiro semestre do seu
curso, dentre as inmeras novidades que vocs encontraro, estar a disciplina de Introduo Cincia da
Computao onde vocs iro aprender os elementos bsicos da programao de computadores e tero contato
com alguns dos conceitos fundamentais da Cincia da Computao. Pela segunda vez no IME/USP, em 2004 a
disciplina ser baseada numa das mais modernas e sofisticadas linguagens de programao: Java. Pela primeira
vez, vamos utilizar esta apostila e esperamos que ela lhes ajude na fascinante empreitada de aprender uma
linguagem de programao.
Esperamos melhorar a apostila sempre que possvel. Portanto, se voc achar algum erro ou tiver alguma
sugesto para melhor-la, no deixe de nos escrever.

Abraos e um bom 2004!

So Paulo, fevereiro de 2004.


Alfredo Goldman, Fabio Kon e Paulo J. Silva e Silva

xi

xii

PREFCIO

Captulo 1

Teatro de Objetos
1.1 Introduo
O Teatro de Objetos uma atividade realizada com os alunos de Introduo Cincia da Computao durante
a primeira aula da disciplina. O objetivo fazer com que os alunos vivenciem um jogo interativo do qual
participem vrios "objetos" realizando diferentes formas de aes e comunicaes. Os conceitos de orientao
a objetos empregados no teatro no so explicitamente explicados j na primeira aula mas sero abordados ao
longo da disciplina. A primeira metade da primeira aula dedicada a uma conversa informal com os alunos
explicando quais so os objetivos desta disciplina (e do curso inteiro, se for o caso). tambm interessante fazer
perguntas sobre contatos prvios que os alunos tiveram com informtica e com programao. bom deixar
claro que a disciplina pode ser acompanhada por uma pessoa que nunca viu um computador na frente em sua
vida, mas que no uma disciplina fcil, preciso se empenhar. Na segunda metade da aula, dizemos aos
alunos que vamos exercitar as suas habilidades dramticas: para ilustrar o funcionamento de um programa de
computador complexo, ns vamos fazer de conta que somos partes de um programa de computador trabalhando
em conjunto para atingir um certo objetivo. Podemos fazer um certo suspense sobre qual o objetivo (simular
uma disputa de pnaltis) e sobre como ele ser alcanado.

1.2 Disputa de Pnaltis


A "pea" encenada em 2003 representar uma disputa de pnaltis entre dois times e contar com a participao
de cerca de 26 atores desempenhando 8 papis. Os papis so:
Tcnico (2 atores)
Juiz (1 ator)
Bandeirinha (2 atores)
Gandula (1 ator)
Jogador. Os jogadores so divididos em dois tipos:
Goleiro (2 atores desempenham este papel)
1

CAPTULO 1. TEATRO DE OBJETOS


Batedor de pnalti (10 atores)
Torcedor. Os torcedores so divididos em dois tipos:
Torcedor educado (4 atores)
Torcedor mal-educado (4 atores)

O professor ser responsvel por escolher os alunos que desempenharo cada papel. Se houver limitao
de espao, conveniente que os 8 torcedores fiquem em suas prprias carteiras para no tumultuar muito o
ambiente. Obviamente, o professor pode tambm aumentar ou diminuir o nmero de torcedores e de batedores
de pnalti. Para desempenhar o papel de torcedores, uma boa dica o professor escolher alunos que paream
bem barulhentos e faladores (por exemplo, a turma do fundo). Ao escolher os atores, o professor dever
entregar um carto preso com um barbante que ficar pendurado no pescoo do ator e conter informaes
sobre o papel desempenhado pelo autor. As informaes so:
1. Nome do papel
2. Mensagens que o personagem capaz de entender
3. Atributos do personagem
Os trs tipos de informao acima j devem vir pr-escritos caneta no carto mas o valor dos atributos do
personagem devem ser escritos na hora lpis pelo professor. Alguns papis, como o Juiz, no possuem
nenhum atributo. Outros papis podem possuir um ou mais atributos, o Jogador, por exemplo pode possuir
como atributos o nome do time ao qual pertence e o nmero da sua camisa. No caso de o jogador ser um
Goleiro, o atributo nmero da camisa pode vir escrito caneta como valendo 1.
Alm deste carto que fica pendurado no pescoo do ator, cada ator recebe um script descrevendo o seu
comportamento: para cada mensagem recebida pelo ator, o script descreve quais aes devem ser tomadas pelo
ator.
O professor no deve se esquecer de trazer uma bola para esta atividade e deve tomar cuidado para que
nenhuma janela seja quebrada durante a realizao da atividade. O tempo total estimado para a realizao da
atividade de 60 minutos.
Eis uma descrio detalhada dos dados que devero aparecer nos cartes descritivos e no script (comportamento) de cada um dos 26 atores participantes da encenao.
1. Goleiro
Carto de Identificao
Nome do Papel: Goleiro
Mensagens que entende: SuaVez, Cobrana Autorizada, VenceuOTimeX
Atributos: Time:, Camisa nmero: 1
Comportamento (Script)
mensagem: SuaVez ao: posiciona-se na frente do gol e fica esperando pela cobrana do
pnalti.

1.2. DISPUTA DE PNALTIS

mensagem: CobranaAutorizada ao: concentra-se na bola que ser chutada pelo adversrio e faz de tudo para no deixar que a bola entre no gol. O goleiro no pode se adiantar
antes do chute do adversrio. Aps a cobrana sair do gol para dar lugar ao goleiro adversrio.
mensagem: VenceuOTimeX ao: se TimeX igual ao atributo Time no seu carto de identificao, comemore; caso contrrio, xingue o juiz (polidamente! :-).
2. Batedor de Pnalti
Carto de Identificao
Nome do Papel: Batedor de Pnalti
Mensagens que entende: SuaVez, CobranaAutorizada, VenceuOTimeX
Atributos: Time:, Camisa nmero:
Comportamento
mensagem: SuaVez ao: posiciona-se na frente da bola e fica esperando pela autorizao
do juiz.
mensagem: CobranaAutorizada ao: chuta a bola tentando marcar um gol. Aps a
cobrana voltar para junto do seu tcnico para dar lugar prxima cobrana.
mensagem: VenceuOTimeX ao: se TimeX igual ao atributo Time no seu carto de identificao, comemore; caso contrrio, xingue o juiz (polidamente! :-).
3. Torcedor Educado
Carto de Identificao
Nome do Papel: Torcedor Educado
Mensagens que entende: Ao, VenceuOTimeX
Atributos: Time:, Camisa nmero: 12
Comportamento
mensagem: Ao ao: assista ao jogo emitindo opinies inteligentes sobre o andamento
da peleja e manifestando o seu apreo e desapreo pelo desenrolar da disputa.
mensagem: VenceuOTimeX ao: se TimeX igual ao atributo Time no seu carto de
identificao, comemore e faa um comentrio elogioso sobre o seu time; caso contrrio, elogie
o adversrio e parabenize o seu time pelo empenho.
4. Torcedor Mal-Educado
Carto de Identificao
Nome do Papel: Torcedor Mal-Educado
Mensagens que entende: Ao, VenceuOTimeX
Atributos: Time:, Camisa nmero: 12
Comportamento

CAPTULO 1. TEATRO DE OBJETOS


mensagem: Ao ao: assista ao jogo emitindo opinies duvidosas sobre o andamento da
peleja e manifestando a sua raiva ou alegria pelo desenrolar do jogo.
mensagem: VenceuOTimeX ao: se TimeX igual ao atributo Time no seu carto de identificao, xingue o adversrio. Caso contrrio, xingue o adversrio desesperadamente (mas, por
favor, no se esquea que estamos em uma universidade).
5. Juiz
Carto de Identificao
Nome do Papel: Juiz
Mensagens que entende: Ao, Irregularidade
Comportamento
mensagem: Ao ao: coordene o andamento da disputa de pnaltis enviando mensagens
SuaVez para o tcnico do time batedor e para o goleiro defensor a cada nova batida. Quando os
personagens estiverem apostos, emita a mensagem CobranaAutorizada. Faa a contagem
de gols e quando houver um vencedor, emita a mensagem VenceuOTimeX onde TimeX o nome
do time vencedor. A disputa de pnaltis feita alternadamente, 5 cobranas para cada time. Se
no houver um ganhador aps as 5 cobranas, so feitas novas cobranas alternadamente at
que haja um vencedor.
mensagem: Irregularidade ao: se a mensagem foi enviada por um Bandeirinha, ignore
a cobrana recm-efetuada e ordene que ela seja repetida enviando a mensagem RepitaCobrana
ao tcnico apropriado.
6. Gandula
Carto de Identificao
Nome do Papel: Gandula
Mensagens que entende: CobranaAutorizada
Comportamento
mensagem: CobranaAutorizada ao: preste ateno cobrana do pnalti. Aps a
concluso da cobrana, pegue a bola e leve-a de volta marca de pnalti.
7. Tcnico
Carto de Identificao
Nome do Papel: Tcnico
Mensagens que entende: SuaVez, RepitaCobrana, VenceuOTimeX
Atributos: Time:
Comportamento
mensagem: SuaVez ao: escolha um dos seus jogadores para efetuar a cobrana e envie-o
a mensagem SuaVez. No repita jogadores nas 5 cobranas iniciais.

1.2. DISPUTA DE PNALTIS

mensagem: RepitaCobrana ao: envie a mensagem SuaVez para o jogador que acabou
de efetuar a cobrana.
mensagem: VenceuOTimeX ao: se TimeX igual ao atributo Time no seu carto de identificao, comemore; caso contrrio, diga que o seu time foi prejudicado pela arbitragem e que
futebol uma caixinha de surpresas.
8. Bandeirinha
Carto de Identificao
Nome do Papel: Bandeirinha
Mensagens que entende: Cobrana Autorizada, VenceuOTimeX
Comportamento
mensagem: CobranaAutorizada ao: verifique se o goleiro realmente no avana antes
de o batedor chutar a bola. Caso ele avance, envie uma mensagem Irregularidade para o
Juiz.
mensagem: VenceuOTimeX ao: se TimeX no o nome do time da casa, distancie-se da
torcida pois voc acaba de se tornar um alvo em potencial.

CAPTULO 1. TEATRO DE OBJETOS

Captulo 2

Histria da Computao
Quais novidades veremos nesta aula?
a histria da computao
evoluo da arquitetura do computador
evoluo das linguagens de programao

2.1 Histria da Computao e Arquitetura do Computador


baco (Soroban em japons) (criado ~2000 anos atrs)
Blaise Pascal, 1642 (pai da calculadora)
o primeiro computador (calculadora) digital,
o capaz de somar
o entrada atravs de discos giratrios
o ajudou seu pai, coletor de impostos
Leibniz (inventou 1671, construu 1694)
computador capaz de somar e multiplicar
criou o mecanismo de engrenagens do "vai-um" usado at hoje
Avanos nas calculadoras de mesa -> 1890 mquinas podiam:
acumular resultados parciais
armazenamento e reentrada automtica de resultados passados (memria)
7

CAPTULO 2. HISTRIA DA COMPUTAO


imprimir resultados em papel
Charles Babbage (Prof. Matemtica em Cambridge, Inglaterra)
1812: notou que muito do que se fazia em matemtica poderia ser automatizado
iniciou projeto do "Difference Engine" (Mquina/Engenho/Engenhoca de Diferenas)
1822: terminou um prottipo da mquina e obteve financiamento do governo p/ constru-la
1823: iniciou construo (usaria motor a vapor, seria totalmente automtico, imprimiria o resultado
e teria um programa fixo)
1833: depois de 10 anos teve uma idia melhor e abandonou tudo
Nova idia: mquina programvel, de propsito geral: "Analytical Engine" (Mquina Analtica)
manipularia nmeros de 50 dgitos
memria de 1000 dgitos
estaes de leitura leriam cartes perfurados similares ao de tear (Jacquard)
mas ele no consegui constru-lo
tecnologia mecnica da poca era insuficiente
pouca gente via a necessidade para tal mquina
Ada Lovelace (me da programao) escreveu programas para o engenho analtico; inventou a
palavra algoritmo em homenagem ao matemtico Al-Khawarizmi (820dC)
a mquina foi finalmente construda pelo governo ingls nos anos 1990 (e funciona!)
URL do vdeo do Roy?
Herman Hollerith, 1890
criou cartes perfurados para uso no censo americano
tecnologia levou criao da International Business Machines (IBM)
MARK 1, criada em 1937 por Howard Aiken, prof. de Matemtica Aplicada de Harvard
calculadora eletromecnica com motor eltrico
pesava 5 toneladas, usava toneladas de gelo para refrigerao
multiplicava dois nmeros de 23 digitos em 3 segundos
John Atanasoff, 1939
calculadora com vlvulas a vcuo (240 vlvulas)
resolvia equaes lineares, diferenciais e de balstica
manipulava nmeros binrios
Rumo a programabilidade

2.1. HISTRIA DA COMPUTAO E ARQUITETURA DO COMPUTADOR

Alan Turing,
Trabalhou para o exrcito ingls ajudando a quebrar o cdigo criptogrfico da mquina Enigma
criada pelos Alemes.
Realizou importantes contribuies prticas e tericas Cincia da Computao.
1912: nasce em Londres
1935: Ganha bolsa para realizar pesquisas no Kings College, Cambridge
1936: Elaboora mquina de Turing, pesquisas em computabilidade
1936-38: Princeton University. Ph.D. Lgica, lgebra, Teoria dos Nmeros
1938-39: Cambridge. apresentado mquina Enigma dos alemes
1939-40: The Bombe, mquina para decodificao do Enigma criada em Bletchley Park
1939-42: quebra Enigma do U-boat, aliados vencem batalha do Atlntico
1943-45: Consultor-chefe anglo-americano para criptologia.
1947-48: Programao, redes neurais e inteligncia artificial
1948: Manchester University
1949: Pesquisas sobre usos do computador em clculos matemticos avanados.
1950: Prope teste de Turing para inteligncia de mquinas.
1952: Preso por homossexualidade, perde privilgios militares
1953-54: Trabalho no finalizado em biologia e fsica; tem sua reputao e vida destrudas pelos
militares ingleses.
1954: Suicida-se em Wilmslow, Cheshire.
Livro interessante sobre sua vida e obra: Alan Turing: the Enigma de Andrew Hodges, 2000.
Stio sobre a vida de Turing mantido pelo autor deste livro: http://www.turing.org.uk/turing.
Aiken declarou em 1947 que nunca haveria necessidade de mais de um ou dois computadores
programveis e que os projetos neste sentido deveriam ser abandonados.
ENIAC, 1945
considerado o primeiro computador eletrnico
nmeros de 10 digitos decimais
300 multiplicaes ou 5000 somas por segundo
17486 vlvulas, alguma queimava quase que diariamente
6000 comutadores manuais e centenas de cabos usados na programao
programao era muito difcil
Arquitetura do ENIAC

10

CAPTULO 2. HISTRIA DA COMPUTAO

Figura 2.1: Arquitetura do ENIAC

Figura 2.2: Arquitetura de Von Neumann

programa especificado manualmente em "hardware" com conexes semelhantes quelas que as


velhas telefonistas utilizavam
memria de dados separada do controle e do programa
o controle formado por circuitos eletro-eletronicos
John Von Neumann, matemtico, 1945
estudo abstrato de modelos de computao levou arquitetura do computador moderno
o programa deve ser guardado no mesmo lugar que os dados: na memria
Arquitetura de Von Neumann (indicar indcio de sistema operacional) (hoje em dia existe memria
ROM, RAM, flash RAM...)
Anos 50
1953: IBM vende 15 mquinas baseadas no modelo de Neumann
transistores
memria magntica ("magnetic core memory")

2.1. HISTRIA DA COMPUTAO E ARQUITETURA DO COMPUTADOR

11

Anos 60
circuitos impressos / cirtuitos integrados (chips)
crescimento segundo lei de Moore at hoje (VLSI)
computao limitada a poucos computadores de grande porte
Anos 70
indo contra o modelo centralizador da IBM, gerao sexo, drogas e rock-and-roll da California
exige a democratizao da informtica
Revista esquerdista da Universidade da California em Berkeley Peoples Computer Company defende a criao de computadores pessoais e de cooperativas de informao.
Steve Jobs cria Apple em garagem ~ 1975, investe lucros do Apple II em shows de Rock (82)
Nasce a Microsoft
Governo da California apia microinformtica
Anos 80
IBM lana PC (1981)
Apple lana MacIntosh (1984)
Xerox inventa e Apple comercializa interface baseada em janelas ("Windows")
Microsoft cresce comercializando o sistema operacional simplista MS-DOS para IBM-PCs (O DOS
era uma verso simplificada do CPM que, por sua vez, era uma verso simplificada do UNIX)
Comea o movimento do software livre
Anos 90
Microsoft pega carona na exploso de vendas de PCs, utiliza tcnicas de marketing agressivas
(consideradas por alguns estudiosos como moralmente questionveis) para controlar mercado de
software, estabelecendo quase um monoplio em certas reas.
Intensifica-se o movimento por software livre
Nasce o Linux e uma nova forma de desenvolvimento de software baseada em comunidades distribudas atravs da Internet.
No final da dcada, governo americano percebe o perigo que a Microsoft representa e inicia batalha
judicial contra a empresa (em 2002, aps a vitria dos conservadores na eleio nos EUA, o governo
termina um processo judicial que havia iniciado; as sanes empresa so mnimas).
Sculo XXI
Computadores de Mo
Sistemas Embutidos
Computao Ubqua

12

CAPTULO 2. HISTRIA DA COMPUTAO

2.2 E a evoluo do software?


Paralelamente evoluo do hardware dos computadores eletrnicos, ocorreu tambm a evoluo do software
e das linguagens de programao utilizadas para desenvolv-lo. Inicialmente, as linguagens estavam bem
prximas ao funcionamento dos circuitos do hardware; paulatinamente, as linguagens foram se aproximando
da linguagem natural utilizada pelos humanos em seu dia-a-dia.
A mquina de Babbage s poderia ser programada com a troca fsica de engrenagens;
1945, no ENIAC, a programao era feita mudando chaves, e trocando a posio de cabos;
1949-50, primeira linguagem binria, a programao era feita mudando os comandos de zero a um, e
vice-versa;
1951, Grace Hooper cria o primeiro compilador, A0, programa que transforma comandos em 0s e 1s.
1957, primeira linguagem de programao de alto nvel: FORTRAN (Formula Translating) (John Backus
da IBM).
1958, criao de um padro universal de linguagem: ALGOL 58 (algoritmic language) (origem da maioria das linguagens modernas). Primeira linguagem estruturada;
1958, John McCarthy do MIT cria o LISP (List Processing), inicialmente projetada para uso em inteligncia artificial. Nela tudo se baseia em listas. Ainda usada hoje em dia;
1959, FORTRAN era eficaz para manipulao de nmeros, no para entrada e sada: foi criada COBOL
(Common Bussines Oriented Langaguage)
1964, criao do Basic (Beginners All-purpose Symbolic Instruction Code);
1965, criao de uma linguagem especfica para a simulao (SIMULA-1) por Ole-Johan Dahl and Kristen Nygaard. considerada a base das linguagens orientadas a objetos;
1966, criao da linguagem Logo para desenhos grficos (a linguagem da tartaruga);
1967, Simula-67, uma linguagem de uso geral incluindo todos os conceitos fundamentais de orientao
a objetos;
1968, criao da linguagem PASCAL por Niklaus Wirth. Principal interesse: linguagem para o ensino.
Combinou as melhores caractersticas de Cobol, Fortran e Algol, foi uma linguagem bem utilizada;
1970, PROLOG, linguagem para programao lgica.
1972, criao da linguagem C (Denis Ritchie). Supriu as deficincias da linguagem Pascal, e teve sucesso
quase imediato;
1972, linguagem Smalltalk (desenvolvida por Alan Kay, da Xerox), OO ganha fora;
1983, criadas extenses de C incluindo suporte para OO: C++ e Objective-C

2.2. E A EVOLUO DO SOFTWARE?

13

1987, linguagens baseadas em scripts, p.ex. Perl, desenvolvida por Larry Wall. Ferramentas de UNIX
como sed e awk no eram suficientes;
1994, Java divulgada como a linguagem para a Internet;

14

CAPTULO 2. HISTRIA DA COMPUTAO

Captulo 3

Conversor de Temperaturas
Quais novidades veremos nesta aula?
primeiro programa em Java

3.1 Analogia entre dramatizao da disputa de pnaltis e Programao Orientada a Objetos


Terminologia Teatral
personagem (papel)
ator
envio de mensagem

Terminologia de Programao Orientada a Objetos


classe (tipo)
objeto
envio de mensagem, chamada de mtodo ou chamada de funo

Na dramatizao, podamos enviar uma mensagem (dizer alguma coisa) para um ator. Na programao orientada a objetos, podemos enviar uma mensagem para (ou chamar um mtodo de) um objeto.
Os cartes de identificao definem os papis dos atores e os scripts especificavam o comportamento dos
atores no decorrer da pea. A linguagem Java permite que ns especifiquemos a mesma coisa. Um carto de
identificao tem 3 partes, essas mesmas 3 partes aparecem na definio de uma classe em Java. Por exemplo,
o bandeirinha em Java seria mais ou menos assim:
class Bandeirinha
{
CobranaAutorizada
{
/ / a q u i vem a d e s c r i o do que o b a n d e i r i n h a f a z quando r e c e b e e s t a mensagem
}
VenceuOTime ( NomeDoTime )
{
/ / a q u i vem a d e s c r i o do que o b a n d e i r i n h a f a z quando r e c e b e e s t a mensagem
}
}

15

16

CAPTULO 3. CONVERSOR DE TEMPERATURAS

3.2 Um exemplo real em Java: um conversor para transformar temperaturas


de Celsius para Fahrenheit
Sempre o primeiro passo antes de programar analisar o problema.
F 32 C
9
9
= F 32 = C F = C + 32
9
5
5
5
traduzindo isso para Java temos F=9*C/5+32. A seguir iremos criar diversas classes para realizar a converso entre Celsius e Fahrenheit.
1. Primeira tentativa: programa em Java para converter 40C para Fahrenheit.
c l a s s Conversor
{
int celsiusParaFahrenheit ()
{
r e t u r n 9 40 / 5 + 3 2 ;
}
}

para executar este conversor dentro do DrJava, podemos digitar o seguinte na janela do interpretador
(chamada de interactions):
C o n v e r s o r g a b r i e l = new C o n v e r s o r ( ) ;
gabriel . celsiusParaFahrenheit ()

o DrJava imprimir o valor devolvido pelo mtodo celsiusParaFahrenheit do objeto gabriel.


limitao: sempre converte a mesma temperatura.
2. Segunda tentativa: conversor genrico de temperaturas Celsius -> Fahrenheit. capaz de converter
qualquer temperatura de Fahrenheit para Celsius.
c l a s s Conversor2
{
int celsiusParaFahrenheit ( int c )
{
return 9 c / 5 + 32;
}
}

para executar este conversor dentro do DrJava, podemos digitar o seguinte na janela do interpretador:
C o n v e r s o r 2 d a n i e l = new C o n v e r s o r 2 ( ) ;
daniel . celsiusParaFahrenheit (100)

o DrJava imprimir o valor devolvido pelo mtodo celsiusParaFahrenheit do objeto daniel.


limitao: essa classe manipula apenas nmeros inteiros. Mas, em geral, temperaturas so nmeros
reais, fracionrios, ento nmeros inteiros no so suficientes. Quando o computador opera com
nmeros inteiros, os nmeros so truncados, ou seja 30.3 se torna 30 e 30.9 tambm se torna 30.

3.2. UM EXEMPLO REAL EM JAVA: UM CONVERSOR PARA TRANSFORMAR TEMPERATURAS DE CELSIUS PARA
Note que devido limitao acima, se tivssemos escrito a frmula como 95 C + 32 o clculo seria
errado pois 95 = 1 se considerarmos apenas a parte inteira da diviso. Assim, o programa calcularia
apenas 1 C + 32 o que seria errado.
Para corrigir isso, usamos nmeros de ponto flutuante (floating point numbers). Esse nome se deriva
do fato de que internamente os nmeros so representados de forma parecida a potncias de 10 onde,
variando o expoente da potncia, movemos (flutuamos) o ponto decimal para a esquerda ou para a direita.
De floating point vem o tipo float da linguagem Java. Nmeros do tipo float so armazenados em 4
bytes e tem uma preciso 23 bits (o que equivale a aproximadamente ? casas decimais). No entanto, quase
sempre so utilizados nmeros de ponto flutuante com preciso dupla que so chamados de double. Em
Java, um double ocupa 8 bytes e tem preciso de 52 bits o que equivale a aproximadamente ? casas
decimais. Por comodidade, daqui para frente sempre que precisarmos de nmeros fracionrios, vamos
utilizar o tipo double.
3. Terceira tentativa: conversor genrico usando double
c l a s s Conversor3
{
double c e l s i u s P a r a F a h r e n h e i t ( double c )
{
return 9.0 c / 5.0 + 3 2 . 0 ;
}
}

limitao: s faz converso em um dos sentidos


4. Quarta e ltima verso: converso de mo dupla
c l a s s Conversor4
{
double c e l s i u s P a r a F a h r e n h e i t ( double c )
{
return 9.0 c / 5.0 + 3 2 . 0 ;
}
double f a h r e n h e i t P a r a C e l s i u s ( double f )
{
return 5.0 ( f 3 2 . 0) / 9 . 0 ;
}
}

para executar este conversor dentro do DrJava, podemos digitar o seguinte na janela do interpretador:
C o n v e r s o r 4 a n d e r s = new C o n v e r s o r 4 ( ) ;
anders . celsiusParaFahrenheit ( 3 7 . 8 ) ;
anders . FahrenheitParaCelsius ( 20.3);

Note que, para que o seu programa fique bem legvel e elegante, muito importante o alinhamento dos
abre chaves { com os fecha chaves } correspondentes. Em programas mais complexos, esse correto
alinhamento (indentao) ajuda muito a tornar o programa mais claro para seres humanos.

18

CAPTULO 3. CONVERSOR DE TEMPERATURAS

3.3 Exerccios:
1. Crie uma classe Conversor5 que inclua tambm a escala Kelvin (K). Esta classe deve conter conversores
entre as trs escalas de temperatura (Celsius, Fahrenheit e Kelvin), totalizando seis funes. A relao
entre as trs escalas dada por:
F 32 C K 273
= =
9
5
5

Captulo 4

Testes Automatizados
Quais novidades veremos nesta aula?
comando if e else;
comparaes == (igualdade) e != (diferena);
definio de variveis inteiras e de ponto flutuante.
impresso de texto.

4.1 Testes
Desde o incio, a computao sempre esteve sujeita erros. O termo bug, para denotar erro, tem uma origem
muito anterior (vem de um inseto que causava problemas de leitura no fonogrfo de Thomas Edison em 1889).
Vrias outras histrias reais, ou nem tanto, tambm apareceram no incio da informtica. Infelizmente, muito
difcil garantir que no existam erros em programas. Uma das formas de se garantir que certos erros no vo
ocorrer testando algumas situaes.
Apesar da frase clebre de Edsger Dijsktra que testes podem apenas mostrar a presena de erros, e no
a sua ausncia, eles podem ser os nossos grandes aliados no desenvolvimento de programas corretos. Logo,
intuitivamente, quanto mais testes fizermos em um programa, mais confiantes podemos ficar com relao ao
seu funcionamento. Por outro lado, ns podemos usar o prprio computador para nos ajudar, isto , podemos
criar testes automatizados. Ao invs de fazermos os testes na mo, faremos com que o computador seja
capaz de verificar o funcionamento de uma seqncia de testes. Veremos nesta aula como desenvolver testes
automatizados, passo a passo, para os conversores de temperatura vistos anteriormente.
No incio da computao no havia uma preocupao muito grande com os testes, eles eram feitos de forma
manual pelos prprios programadores, os grandes testadores eram os usurios finais. interessante notar que
isto ainda acontece com alguns produtos ainda hoje. Com o aparecimento da Engenharia de Software ficou
clara a necessidade de se efetuar testes, tanto que em vrias empresas de desenvolvimento de software existe
a figura do testador, responsvel por tentar encontrar erros em sistemas. Hoje existe uma tendncia em se
considerar que testes automatizados so muito importantes, devendo ser escritos mesmo antes de se escrever o
cdigo propriamente dito, tcnica esta chamada de testes a priori.
19

20

CAPTULO 4. TESTES AUTOMATIZADOS

Veremos como testar os diversos conversores de temperatura. Como testar o nosso primeiro programa em
Java (Conversor).
C o n v e r s o r c1 = new C o n v e r s o r ( )
/ / a r e s p o s t a e s p e r a d a o e q u i v a l e n t e a 40C em F
i f ( c1 . c e l s i u s P a r a F a h r e n h e i t ( ) == 1 0 4 )
System . o u t . p r i n t l n ( " F u n c i o n a " ) ;
else
System . o u t . p r i n t l n ( " No f u n c i o n a " ) ;

Note que para fazer o teste utilizamos o comando condicional if else. O formato genrico deste comando
o seguinte.
i f (CONDIO)
COMANDO1;
else
COMANDO2;

Se a CONDIO verdadeira, o COMANDO-1 executado, caso contrrio, o COMANDO-2 executado.


A classe Conversor2 possui um mtodo que aceita um parmetro, veja o teste abaixo:
C o n v e r s o r 2 c2 = new C o n v e r s o r 2 ( ) ;
/ / c r i a duas v a r i v e i s i n t e i r a s
int entrada = 40;
int r e s p o s t a = 104;
/ / a r e s p o s t a e s p e r a d a o e q u i v a l e n t e a e n t r a d a C em F
i f ( c2 . c e l s i u s P a r a F a h r e n h e i t ( e n t r a d a ) == r e s p o s t a )
System . o u t . p r i n t l n ( " F u n c i o n a " ) ;
else
System . o u t . p r i n t l n ( " No f u n c i o n a " ) ;

Note que, para realizar o teste acima ns definimos duas variveis inteiras chamadas de entrada e resposta.
A linha
int entrada = 40;

faz na verdade duas coisas. Primeiro, ela declara a criao de uma nova varivel (int entrada;) e, depois,
atriubui um valor inicial a esta varivel (entrada = 40;). Na linguagem Java, se o valor inicial no atribudo,
o sistema atribui valor 0 automaticamente.
Podemos tambm testar o Conversor2 para outros valores. Por exemplo, para as entradas e respostas: 20
(68) e 100 (212).
e n t r a d a = 2 0 ; / / como a s v a r i v e i s j f o r a m d e c l a r a d a s acima , b a s t a usl a s
re spos ta = 68;
i f ( c2 . c e l s i u s P a r a F a h r e n h e i t ( e n t r a d a ) == r e s p o s t a )
System . o u t . p r i n t l n ( " F u n c i o n a " ) ;
else
System . o u t . p r i n t l n ( " No f u n c i o n a " ) ;
entrada = 100;
r e s p o s t a = 212;
i f ( c2 . c e l s i u s P a r a F a h r e n h e i t ( e n t r a d a ) == r e s p o s t a )
System . o u t . p r i n t l n ( " F u n c i o n a " ) ;

21

4.1. TESTES
else
System . o u t . p r i n t l n ( " No f u n c i o n a " ) ;

No programa acima o texto Funciona vai ser impresso na tela a cada sucesso, isso poder causar uma
poluio visual caso tenhamos dezenas ou centenas de testes. O ideal para um testador que ele fique silencioso
caso os testes dem certo e chame a ateno caso ocorra algum erro. Podemos ento mudar o programa para:
C o n v e r s o r 2 c2 = new C o n v e r s o r 2 ( ) ;
int entrada = 40;
int r e s p o s t a = 104;
i f ( c2 . c e l s i u s P a r a F a h r e n h e i t ( e n t r a d a ) ! = r e s p o s t a )
System . o u t . p r i n t l n ( " No f u n c i o n a p a r a 40 " ) ;
entrada = 20;
re spos ta = 68;
i f ( c2 . c e l s i u s P a r a F a h r e n h e i t ( e n t r a d a ) ! = r e s p o s t a )
System . o u t . p r i n t l n ( " No f u n c i o n a p a r a 20 " ) ;
entrada = 100;
r e s p o s t a = 212;
i f ( c2 . c e l s i u s P a r a F a h r e n h e i t ( e n t r a d a ) ! = r e s p o s t a )
System . o u t . p r i n t l n ( " No f u n c i o n a p a r a 100 " ) ;
System . o u t . p r i n t l n ( " Fim d o s t e s t e s " ) ;

Note que o comando if acima foi utilizado sem a parte do else o que perfeitamente possvel. Adicionamos tambm uma linha final para informar o final dos testes. Ela importante no caso em que todos os testes
do certo para que o usurio saiba que j terminamos a execuo de todos os testes.
Uma forma de simplificar os comandos de impresso usar a prpria entrada como parmetro, isto pode
ser feito da seguinte forma:
System . o u t . p r i n t l n ( " No f u n c i o n a p a r a " + e n t r a d a ) ;

Criaremos agora os testes para o Conversor4. Mas agora, devem ser testados os seus dois mtodos. Introduziremos um testador automtico criando uma classe com apenas um mtodo que faz o que vimos.
class TestaConversor4
{
int testaTudo ()
{
C o n v e r s o r 4 c4 = new C o n v e r s o r 4 ( ) ;
double t c = 1 0 . 0 ;
double t f = 5 0 . 0 ;
i f ( c4 . c e l s i u s P a r a F a h r e n h e i t ( t c ) ! = t f )
System . o u t . p r i n t l n ( "C> F no f u n c i o n a
i f ( c4 . f a h r P a r a C e l s i u s ( t f ) ! = t c )
System . o u t . p r i n t l n ( " F> C no f u n c i o n a
tc = 20.0;
tf = 68.0;
i f ( c4 . c e l s i u s P a r a F a h r e n h e i t ( t c ) ! = t f )
System . o u t . p r i n t l n ( "C> F no f u n c i o n a
i f ( c4 . f a h r P a r a C e l s i u s ( t f ) ! = t c )
System . o u t . p r i n t l n ( " F> C no f u n c i o n a

para " + tc ) ;
para " + t f ) ;

para " + tc ) ;
para " + t f ) ;

22

CAPTULO 4. TESTES AUTOMATIZADOS


tc = 101.0;
tf = 213.8;
i f ( c4 . c e l s i u s P a r a F a h r e n h e i t ( t c ) ! = t f )
System . o u t . p r i n t l n ( "C> F no f u n c i o n a p a r a " + t c ) ;
i f ( c4 . f a h r P a r a C e l s i u s ( t f ) ! = t c )
System . o u t . p r i n t l n ( " F> C no f u n c i o n a p a r a " + t f ) ;
System . o u t . p r i n t l n ( " F i n a l d o s t e s t e s " ) ;
return 0;
}

Agora, vamos treinar o que aprendemos com alguns exerccios. Em particular, o exerccio 3 de refatorao
muito importante.

4.2

Exerccios

1. Escreva uma classe Ol com um nico mtodo cumprimenta que, a cada chamada, cumprimenta o
usurio de uma entre 3 maneiras diferentes. Dica: use um atributo para, dependendo de seu valor,
escolher qual das maneiras ser usada; depois de imprimir a mensagem, altere o valor do atributo.
2. Escreva uma classe TestaConversor3 para testar a classe Conversor3.
3. Refatorar a classe TestaConversos4 de modo a eliminar as partes repetidas do cdigo. Dica: Crie um
mtodo que realiza o teste das duas funes.
4. Podemos criar testes para objetos de uma classe que no sabemos como foi implementada. Para tal, basta
conhecermos suas entradas e sadas.
Escreva um teste automatizado para a seguinte classe:
c l a s s Contas
{
double c a l c u l a Q u a d r a d o ( double x ) ;
double c a l c u l a C u b o ( double x ) ;
}

5. Programas confiveis: Se conhecemos uma implementao e sabemos que a mesma funciona de maneira
confivel, ela pode servir de base para o teste de outras implementaes. Caso duas implementaes
diferentes produzam resultados distintos para os mesmos dados de entrada, podemos dizer que pelo
menos uma das duas est errada;
Supondo que a classe Contas do exerccio anterior confivel, escreva um teste automatizado que utiliza
esta classe para testar a classe ContasNaoConfiavel dada abaixo:
c l a s s ContasNaoConfiavel
{
double c a l c u l a Q u a d r a d o ( double x ) ;
double c a l c u l a C u b o ( double x ) ;
}

4.3. RESOLUES

4.3 Resolues
3
i n t t e s t e P o n t u a l ( double tc , double t f )
{
C o n v e r s o r c4 = new C o n v e r s o r 4 ( ) ;
i f ( c4 . c e l s i u s P a r a F a h r e n h e i t ( t c ) ! = t f )
System . o u t . p r i n t l n ( "C> F no f u n c i o n a p a r a " + t c ) ;
i f ( c4 . f a h r P a r a C e l s i u s ( t f ) ! = t c )
System . o u t . p r i n t l n ( " F> C no f u n c i o n a p a r a " + t f ) ;
return 0;
}
int testaTudo ()
{
double t c = 1 0 . 0 ;
double t f = 5 0 . 0 ;
t e s t e P o n t u a l ( tc , t f ) ;
tc = 20.0;
tf = 68.0;
t e s t e P o n t u a l ( tc , t f ) ;
tc = 101.0;
tf = 213.8;
t e s t e P o n t u a l ( tc , t f ) ;
System . o u t . p r i n t l n ( " F i n a l d o s t e s t e s " ) ;
return 0;
}

4
C o n t a s a = new C o n t a s ( ) ;
double x = 4 . 0 ;
i f ( a . c a l c u l a Q u a d r a d o ( x ) != 1 6 . 0 )
System . o u t . p r i n t l n ( " No f u n c i o n a p a r a c a l c u l a r o q u a d r a d o de 4 " ) ;
i f ( a . c a l c u l a C u b o ( x ) != 6 4 . 0 )
System . o u t . p r i n t l n ( " No f u n c i o n a p a r a c a l c u l a r 4 ao cubo " ) ;

23

24

CAPTULO 4. TESTES AUTOMATIZADOS

Captulo 5

Mtodos com vrios parmetros


Quais novidades veremos nesta aula?
Mtodos que devolvem nada (void);
Mtodos com vrios parmetros;
Atributos.

5.1 Mtodos com vrios parmetros


Na ltima aula ns j vimos um mtodo que recebia vrios parmetros. Apesar de no estarmos apresentando
nenhuma novidade conceitual vamos reforar a possibilidade da passagem de mais de um parmetro.
Assim como na passagem de apenas um parmetro, necessrio que o valor passado seja do mesmo tipo
do que o valor que o mtodo est esperando. Por exemplo, se um objeto (ator) tem um mtodo (entende uma
mensagem) que tem como parmetro um nmero inteiro no podemos enviar a este objeto um nmero double.
Apesar de ser intuitivo, tambm vale ressaltar que a ordem dos parmetros importante, na chamada de um
mtodo devemos respeitar a mesma ordem que est na sua definio.
Vamos comear com o clculo da rea de uma circunferncia, onde necessrio apenas um parmetro, o
raio:
class Crculo1
{
double c a l c u l a r e a ( double r a i o )
{
return 3.1415 r a i o r a i o ;
}
}

25

26

CAPTULO 5. MTODOS COM VRIOS PARMETROS

Nota Lingustica: Em Java, o nome de variveis, classes e mtodos pode conter caracteres acentuados. Muitos programadores evitam o uso de acentuao mesmo ao usar nomes
em portugus. Este costume advm de outras linguagens mais antigas, como C, que no
permitem o uso de caracteres acentuados. Voc pode usar caracteres acentuados se quiser mas lembre-se que se voc tiver uma varivel chamada rea, ela ser diferente de
outra chamada area (sem acento); ou seja, se voc decidir usar acentos, dever us-los
consistentemente sempre.
Podemos sofisticar o exemplo calculando tambm o permetro, com o seguinte mtodo:
double c a l c u l a P e r m e t r o ( double r a i o )
{
return 3.1415 2.0 r a i o ;
}

O seguinte trecho de cdigo calcula e imprime a rea e permetro de uma circunferncia de raio 3.0:
C r c u l o 1 c = new C r c u l o 1 ( ) ;
System . o u t . p r i n t l n ( c . c a l c u l a r e a ( 3 . 0 ) ) ;
System . o u t . p r i n t l n ( c . c a l c u l a P e r m e t r o ( 3 . 0 ) ) ;

Vejamos agora uma classe Retngulo que define mtodos para o clculo do permetro e da rea de um
retngulo. Neste caso so necessrios dois parmetros.
c l a s s Retngulo1
{
i n t c a l c u l a r e a ( i n t lado1 , i n t lado2 )
{
return lado1 lado2 ;
}
i n t c a l c u l a P e r m e t r o ( i n t lado1 , i n t lado2 )
{
return 2 ( lado1 + lado2 ) ;
}
}

As chamadas para os mtodos podem ser da seguinte forma:


R e t n g u l o 1 r = new R e t n g u l o 1 ( ) ;
System . o u t . p r i n t l n ( r . c a l c u l a r e a ( 2 , 3 ) ) ;
System . o u t . p r i n t l n ( r . c a l c u l a P e r m e t r o ( 2 , 3 ) ) ;

Mas, assim como no exemplo do teatrinho dos objetos onde os jogadores tinham como caracterstica o time
e o nmero da camisa (atributos), tambm podemos ter algo semelhante para o caso dos retngulos. Podemos
fazer com que os dados sobre os lados sejam caractersticas dos objetos. Isto feito da seguinte forma:
c l a s s Retngulo2
{
int lado1 ;
int lado2 ;

5.1. MTODOS COM VRIOS PARMETROS

27

int calcularea ()
{
return lado1 lado2 ;
}
int calculaPermetro ()
{
return 2 ( lado1 + lado2 ) ;
}
}

Entretando fica faltando algum mtodo para carregar os valores dos lados nas variveis lado1 e lado2.
v o i d c a r r e g a L a d o s ( i n t l 1 , i n t l 2 ) / / e s t e mtodo no d e v o l v e nenhum v a l o r
{
lado1 = l1 ;
lado2 = l2 ;
}

Nota Lingustica: void em ingls significa o vazio, nada, ou nulidade.


O funcionamento de um objeto da classe Retngulo pode ser verificado com o cdigo abaixo:
R e t n g u l o 2 r = new R e t n g u l o 2 ( ) ;
r . carregaLados (3 , 5);
System . o u t . p r i n t l n ( r . c a l c u l a r e a ( ) ) ;
System . o u t . p r i n t l n ( r . c a l c u l a P e r m e t r o ( ) ) ;

Para no perdermos o hbito, tambm veremos como testar esta classe. Neste caso, temos duas opes,
criar diversos objetos do tipo Retngulo, ou carregar diversos lados. Veja abaixo as duas opes:
class TestaRetngulo
{
void t e s t e P o n t u a l ( i n t l1 , i n t l 2 )
{
R e t n g u l o 2 r = new R e t n g u l o 2 ( ) ;
r . c a r r e g a L a d o s ( l1 , l 2 ) ;
i f ( r . c a l c u l a r e a ( ) != l 1 l 2 )
System . o u t . p r i n t l n ( " No f u n c i o n a r e a p a r a l a d o s "
+ l1 + " e " + l2 ) ;
i f ( r . c a l c u l a P e r m e t r o ( ) != 2 ( l 1 + l 2 ) )
System . o u t . p r i n t l n ( " No f u n c i o n a p e r m e t r o p a r a l a d o s "
+ l1 + " e " + l2 ) ;
}
void testaTudo ( )
{
t e s t e P o n t u a l (10 , 20);
testePontual (1 , 2);
testePontual (3 , 3);
}
}

28

CAPTULO 5. MTODOS COM VRIOS PARMETROS

Da mesma forma que os lados foram atributos para a classe Retngulo2, podemos fazer o mesmo para a
classe Crculo1.
class Crculo2
{
double r a i o ;
void c a r r e g a R a i o ( double r )
{
raio = r ;
}
double c a l c u l a r e a ( )
{
return 3.1415 r a i o r a i o ;
}
double c a l c u l o P e r m e t r o ( )
{
return 3.1415 2.0 r a i o ;
}
}

Assim como vimos anteriormente podemos tambm utilizar objetos de uma classe sem conhecer a sua
implementao. Por exemplo suponha que temos acesso a uma classe Clculo que possui o seguinte mtodo:
int calculaPotncia ( int x , int n );

Para calcular a potncia poderiamos ter o seguinte trecho de cdigo:


C l c u l o c = new C l c u l o ( ) ;
System . o u t . p r i n t l n ( " 2 e l e v a d o a 5 i g u a l a : " + c . c a l c u l a P o t n c i a ( 2 , 5 ) ) ;

5.2

Exerccios

Mtodos com vrios parmetros


1. Calcular a mdia aritmtica de 4 notas e dizer se o dono das notas foi aprovado, est de recuperao ou
foi reprovado. Por exemplo,
Entrada:
8.7, 7.2, 9.3, 7.4
5.2, 3.4, 6.5, 2.1
3.4, 5.1, 1.1, 2.0
Sada:
Mdia: 8.15 -> aprovado.
Mdia: 4.3 -> recuperao.
Mdia: 2.9 -> reprovado.
Para isso, crie uma classe Aluno com mtodos que carreguem as 4 notas em variveis p1, p2, p3, p4 e
um mtodo responsvel por calcular a mdia aritmtica das notas e dar o veredito.

5.2. EXERCCIOS

29

Atributos
1. Construa a classe Inteiro que representa um nmero inteiro. Essa classe deve ter os seguintes atributos
e mtodos:

Classe Inteiro
Atributos:
int valor
Valor do inteiro representado.
Mtodos para interao com o usurio da classe:
void carregaValor(int v)
Muda o valor representado por este objeto. O novo valor deve ser v.
int devolveValor()
Devolve o valor representado por este objeto.
int devolveValorAbsoluto()
Devolve o valor absoluto do valor representado por este objeto.
void imprime()
Imprime algo que representa este objeto. Sugesto: imprima o valor.

Exemplo de uso no DrJava:

> Inteiro i = new Inteiro();


> i.carregaValor(14);
> i.devolveValor()
14
> i.carregaValor(-473158);
> i.devolveValor()
-473158
> i.devolveValorAbsoluto()
473158
> i.imprime();
Valor: -473158.

2. Acrescente classe Inteiro algumas operaes matemticas, implementando os seguintes mtodos:

30

CAPTULO 5. MTODOS COM VRIOS PARMETROS


Classe Inteiro
Mais mtodos para interao com o usurio da classe:
int soma(int v)
Soma v ao valor deste objeto (valor + v). Este objeto passa representar o novo
valor, que tambm deve ser devolvido pelo mtodo.
int subtrai(int v)
Subtrai v do valor deste objeto (valor - v). Este objeto passa representar o novo
valor, que tambm deve ser devolvido pelo mtodo.
int multiplicaPor(int v)
Multiplica o valor deste objeto por v (valor * v). Este objeto passa representar o
novo valor, que tambm deve ser devolvido pelo mtodo.
int dividePor(int divisor)
Verifica se divisor diferente de zero. Se no, imprime uma mensagem de erro e
no faz nada (devolve o valor inalterado). Se for, divide o valor deste objeto por
v (valor / divisor, diviso inteira). Este objeto passa representar o novo valor,
que tambm deve ser devolvido pelo mtodo.
Exemplo de uso no DrJava:
> Inteiro i = new Inteiro();
> i.carregaValor(15);
> i.subtrai(20)
-5
> i.devolveValor()
-5
Se quiser, voc tambm pode fazer verses desses mtodos que no alteram o valor representado, apenas
devolvem o valor da conta.

Captulo 6

if else encaixados
Quais novidades veremos nesta aula?
novidade: if else encaixados
exerccio para reforar o que aprendemos at agora.

6.1

if else encaixados

Vamos iniciar programando uma classe para representar um tringulo retngulo. Ela contm um mtodo que,
dados os comprimentos dos lados do tringulo, verifica se o mesmo retngulo ou no.
class TrianguloRetangulo
{
void v e r i f i c a L a d o s ( i n t a , i n t b , i n t c )
{
i f ( a b c ! = 0 ) / / nenhum l a d o pode s e r
{
i f ( a a == b b + c c )
System . o u t . p r i n t l n ( " T r i n g u l o r e t n g u l o
i f ( b b == a a + c c )
System . o u t . p r i n t l n ( " T r i n g u l o r e t n g u l o
i f ( c c == a a + b b )
System . o u t . p r i n t l n ( " T r i n g u l o r e t n g u l o
}
}
}

nulo

. " );
. " );
. " );

O mtodo acima pode ser chamado da seguinte forma:


T r i a n g u l o R e t a n g u l o 1 r = new T r i a n g u l o R e t a n g u l o 1 ( ) ;
r . verificaLados (1 , 1 , 1);
r . verificaLados (3 , 4 , 5);

Limitaes:
31

32

CAPTULO 6. IF ELSE ENCAIXADOS


1. mesmo que um if seja verdadeiro, ele executa os outros ifs. Em particular, se tivssemos um tringulo
retngulo para o qual vrios desses ifs fossem verdadeiros, ele imprimiria esta mensagem vrias vezes
(ser que isso possvel neste caso especfico???);
2. este mtodo s imprime uma mensagem se os dados correspondem s medidas de um tringulo retngulo,
se no um tringulo retngulo, ele no imprime nada. Atravs do uso do else podemos imprimir
mensagens afirmativas e negativas:

class TrianguloRetangulo2
{
void v e r i f i c a L a d o s ( i n t a , i n t b , i n t c )
{
i f ( a b c ! = 0 ) / / nenhum l a d o pode s e r n u l o
{
i f ( a a == b b + c c )
System . o u t . p r i n t l n ( " T r i n g u l o r e t n g u l o . " ) ;
e l s e i f ( b b == a a + c c )
System . o u t . p r i n t l n ( " T r i n g u l o r e t n g u l o . " ) ;
e l s e i f ( c c == a a + b b )
System . o u t . p r i n t l n ( " T r i n g u l o r e t n g u l o . " ) ;
else
System . o u t . p r i n t l n ( " No t r i n g u l o r e t n g u l o . " ) ;
}
e l s e System . o u t . p r i n t l n ( " No t r i n g u l o p o i s p o s s u i l a d o de c o m p r i m e n t o n u l o . " ) ;
}
}

Caso sejam necessrios outros mtodos, como um para o clculo de permetro, interessante colocar os
lados como atributos da classe.
class TrianguloRetangulo3
{
int a , b , c ;
void c a r r e g a L a d o s ( i n t l1 , i n t l2 , i n t l 3 )
{
a = l1 ;
b = l2 ;
c = l3 ;
}
int calculaPerimetro ()
{
return a + b + c ;
}
void v e r i f i c a L a d o s ( )
{
i f ( a b c ! = 0 ) / / nenhum l a d o pode s e r n u l o
{
i f ( a a == b b + c c )
System . o u t . p r i n t l n ( " T r i n g u l o r e t n g u l o . " ) ;
e l s e i f ( b b == a a + c c )
System . o u t . p r i n t l n ( " T r i n g u l o r e t n g u l o . " ) ;

6.2. EXERCCIOS

33

e l s e i f ( c c == a a + b b )
System . o u t . p r i n t l n ( " T r i n g u l o r e t n g u l o . " ) ;
else
System . o u t . p r i n t l n ( " No t r i n g u l o r e t n g u l o . " ) ;
}
else
System . o u t . p r i n t l n ( " No t r i n g u l o p o i s p o s s u i l a d o de c o m p r i m e n t o n u l o . " ) ;
}
}

6.2

Exerccios

1. Voc foi contratado por uma agncia de viagens para escrever uma classe em Java para calcular a converso de reais para dlar de acordo com a taxa de compra e a taxa de venda. Para isso, escreva uma classe
ConversorMonetrio que inclua os seguintes mtodos:
(a) defineTaxaCompra() e defineTaxaVenda().
(b) imprimeTaxas() que imprime o valor das 2 taxas de converso.
(c) vendeDlar() que recebe uma quantia em dlares e devolve o valor correspondente em reais.
(d) compraDlar() que recebe uma quantia em dlares e devolve o valor correspondente em reais.
2. Escreva uma classe Baskara que possui 3 atributos do tipo double correspondentes aos coeficientes a, b
e c de uma equao do segundo grau. Escreva um mtodo para carregar valores nestes atributos e, em
seguida, escreva os 4 mtodos seguintes:
(a) delta() deve calcular o da frmula de Baskara.
(b) nmeroDeRazesReais() deve devolver um inteiro indicando quantas razes reais a equao possui.
(c) razesReais() deve imprimir as razes reais.
(d) razesImaginrias() deve imprimir as razes imaginrias.
Para calcular a raiz quadrada, voc pode utilizar o mtodo java.lang.Math.sqrt(double x), que
recebe um double como parmetro e devolve outro double. Voc pode supor que o primeiro coeficiente,
a, diferente de 0.
3. [Desafio!] So apresentadas a voc doze esferas de aparncia idntica. Sabe-se que apenas uma delas
levemente diferente das demais em massa, mas no se sabe qual, e nem se a massa maior ou menor.
Sua misso identificar essa esfera diferente, e tambm dizer se ela mais ou menos pesada. Para isso
voc tem apenas uma balana de prato (que s permite determinar igualdades/desigualdades). Ah, sim,
pequeno detalhe: o desafio completar a misso em no mais que trs pesagens.
Escreva um programa que resolve esse desafio. O seu programa deve dar uma resposta correta sempre e
tambm informar as trs ou menos pesagens que permitiram concluir a resposta.Como esse problema
um tanto complicado, recomendamos que voc implemente o modelo descrito a seguir.

34

CAPTULO 6. IF ELSE ENCAIXADOS


Classe DesafioDasEsferas
Atributos:
int esferaDiferente
Identificador da esfera com peso diferente.
boolean maisPesada
Diz se a esfera diferente ou no mais pesada que as demais (isto , true
para mais pesada e false para mais leve).
int numPesagens
Representa o nmero de pesagens realizadas.
Mtodos para interao com o usurio:
void defineEsferaDiferente(int esfera, boolean pesada)
Determina qual a esfera diferente (parmetro esfera), e se ela mais pesada ou
no (parmetro pesada). Alm disso, reinicia as pesagens, isto , o nmero de
pesagens realizadas volta a ser zero.
void resolveDesafioDasDozeEsferas()
Resolve o Desafio das Doze das Esferas. Este mtodo deve imprimir as 3 (ou
menos) pesagens feitas, e no final a resposta correta. Este mtodo deve se utilizar
dos mtodos para uso interno descritos abaixo. Dica: na implementao deste
mtodo voc tambm usar uma quantidade grande de ifs e elses encaixados.
Mtodos para uso interno da classe:

int
int
int
int
int
int
int
int
int

pesa1x1(int
pesa2x2(int
pesa3x3(int
pesa4x4(int
d3, int d4)
pesa5x5(int
d2, int d3,
pesa6x6(int
d1, int d2,

e1,
e1,
e1,
e1,

int
int
int
int

d1)
e2, int d1, int d2)
e2, int e3, int d1, int d2, int d3)
e2, int e3, int e4, int d1, int d2,

e1,
int
e1,
int

int
d4,
int
d3,

e2,
int
e2,
int

int e3, int e4, int e5, int d1,


d5)
int e3, int e4, int e5, int e6,
d4, int d5, int d6)

Os mtodos acima (no formato pesa#x#) funcionam de forma semelhante. Eles


representam as possveis pesagens, e devolvem o resultado. Os parmetros representam as esferas que so pesadas, os comeados por e (ou seja, e1, e2, ...)
representam esferas que vo para o prato esquerdo e os comeados por d (d1, d2,
...) so as do prato direito. Lembrando, cada esfera representada por um inteiro
entre 1 e 12. Ento, por exemplo, para comparar as esferas 1, 7 e 3 com as esferas
4, 5 e 6, basta chamar pesa3x3(1,7,3,4,5,6). Os mtodos devem devolver -1 se a
balana pender para o lado esquerdo, 0 se os pesos forem iguais ou 1 se a balana
pender para o lado direito. Esses mtodos tambm devem incrementar o nmero
de pesagens realizadas.

6.2. EXERCCIOS

35

Cada esfera deve ser representada por um inteiro entre 1 e 12. Para representarmos a esfera diferente,
usaremos, alm do identificador inteiro, uma varivel booleana que receber o valor true se a esfera for
mais pesada ou o valor false se a esfera for mais leve.
Importante: note que para que o problema tenha sentido, o mtodo resolveDesafioDasDozeEsferas no
deve de modo algum acessar os atributos esferaDiferente e maisPesada para inferir a resposta. Quem d
pistas para este mtodo sobre o valor desses atributos so os mtodos pesa#x#.
Lembre-se de que voc tambm pode implementar mtodos adicionais, se achar necessrio ou mais
elegante. Ou ainda, se voc j se sente seguro(a), voc pode implementar a(s) sua(s) prpria(s) classe(s).
Exemplo de uso no DrJava:
> DesafioDasEsferas dde = new DesafioDasEsferas();
> dde.defineEsferaDiferente(4, false);
Incio do desafio: esfera 4 mais leve.
> dde.resolveDesafioDasDozeEsferas();
Pesagem 1: 1 2 3 4 5 x 6 7 8 9 10.
Resultado: (1) lado direito mais pesado.
Pesagem 2: 1 2 x 3 4.
Resultado: (-1) lado esquerdo mais pesado.
Pesagem 3: 1 x 2.
Resultado: (0) balana equilibrada.
Resposta: esfera 3 mais leve.
[Resposta errada!]
Note que a resposta est errada! (Alm disso, as pesagens no permitem dar a resposta certa.)

36

CAPTULO 6. IF ELSE ENCAIXADOS

Captulo 7

Programas com Vrios Objetos


Quais novidades veremos nesta aula?
Programas com vrios objetos

7.1 Programas com Vrios Objetos


At agora, todos os programas que vimos lidavam com apenas um objeto. No entanto, podemos ter vrios
programas que lidam com vrios objetos. Estes objetos podem todos pertencer mesma classe, ou podem
pertencer a classes diferentes. Exemplo:
1. Vrios objetos do mesmo tipo
F l o r r o s a = new F l o r ( ) ;
F l o r m a r g a r i d a = new F l o r ( ) ;
F l o r l a r a n j e i r a = new F l o r ( ) ;
rosa . cor ( " vermelha " ) ;
r o s a . aroma ( " m u i t o a g r a d v e l " ) ;
m a r g a r i d a . aroma ( " s u t i l " ) ;
l a r a n j e i r a . aroma ( " d e l i c i o s o " ) ;

2. Vrios objetos de tipos (classes) diferentes:


C a c h o r r o f l o q u i n h o = new C a c h o r r o ( ) ;
Gato mingau = new Gato ( ) ;
R a t o t o p o G i g g i o = new R a t o ( ) ;
Vaca mimosa = new Vaca ( ) ;
floquinho . lata ( ) ;
mingau . mie ( ) ;
to poG iggi o . comaQueijo ( ) ;
mingau . p e r s i g a ( t o p o G i g g i o )
f l o q u i n h o . p e r s i g a ( mingau ) ;
mimosa . p a s s e P o r C i m a ( f l o q u i n h o , mingau , t o p o G i g g i o ) ;

37

38

CAPTULO 7. PROGRAMAS COM VRIOS OBJETOS


Vejamos agora um exemplo de utilizaao de objetos de 3 tipos diferentes em conjunto:
c l a s s Prisma
{
double a l t u r a ;
double areaDaBase ;
void c a r r e g a A l t u r a ( double a )
{
altura = a;
}
void carregaAreaDaBase ( double a )
{
areaDaBase = a ;
}
d o u b l e volume ( )
{
return areaDaBase a l t u r a ;
}
}
c l a s s Quadrado
{
double l a d o ;
void c a r r e g a L a d o ( double l )
{
lado = l ;
}
double a r e a ( )
{
return lado lado ;
}
}
class TrianguloRetangulo
{
double c a t e t o 1 ;
double c a t e t o 2 ;
/ / n o t e a i n d e n t a o s u p e r c o m p a c t a !
void c a r r e g a C a t e t o 1 ( double c ) { c a t e t o 1 = c ; }
void c a r r e g a C a t e t o 2 ( double c ) { c a t e t o 2 = c ; }
double a r e a ( )
{
return c a t e t o 1 c a t e t o 2 / 2 . 0 ;
}
}

Agora, utilizando o interpretador, podemos criar objetos destes vrios tipos e utiliz-los em conjunto:

7.2. EXERCCIO

39

Quadrado q = new Quadrado ( ) ;


T r i a n g u l o R e t a n g u l o t r = new T r i a n g u l o R e t a n g u l o ( ) ;
P r i s m a p r i s m a B a s e Q u a d r a d a = new P r i s m a ( ) ;
P r i s m a p r i s m a B a s e T r i a n g u l a r = new P r i s m a ( ) ;
q . lado ( 1 0 ) ;
tr . cateto1 (20);
tr . cateto2 (30);
prismaBaseQuadrada . c a r r e g a A l t u r a ( 3 ) ;
prismaBaseTriangular . carregaAltura (1);
prismaBaseQuadrada . carregaAreaDaBase ( q . area ( ) ) ;
prismaBaseTriangular . carregaAreaDaBase ( t r . area ( ) ) ;
i f ( p r i s m a B a s e Q u a d r a d a . volume ( ) > p r i s m a B a s e T r i a n g u l a r . volume ( ) )
System . o u t . p r i n t l n ( "O p r i s m a de b a s e q u a d r a d a tem m a i o r volume " ) ;
e l s e i f ( p r i s m a B a s e T r i a n g u l a r . volume ( ) > p r i s m a B a s e Q u a d r a d a . volume ( ) )
System . o u t . p r i n t l n ( "O p r i s m a de b a s e t r i a n g u l a r tem m a i o r volume " ) ;
else
System . o u t . p r i n t l n ( " Ambos o s p r i s m a s tem o mesmo volume " ) ;

Nota sobre o interpretador do DrJava: para conseguir digitar todos os ifs encaixados no interpretador
do DrJava sem que ele tente interpretar cada linha em separado, preciso utilizar Shift+Enter ao invs de
apenas Enter no final de cada linha dos ifs encaixados. Apenas no final da ltima linha (a que contm o
println final) que se deve digitar apenas Enter para que o DrJava ento interprete todas as linhas de
uma vez.

7.2

Exerccio

1. Escreva uma classe Rendimentos que contenha os seguintes mtodos a fim de contabilizar o total de
rendimentos de uma certa pessoa em um certo ano:
rendimentosDePessoaFisica(double);
rendimentosDePessoaJuridica(double);
rendimentosDeAplicacoesFinanceiras(double);
rendimentosNaoTributaveis(double);
double totalDeRendimentosTributaveis();
Em seguida, escreva uma classe TabelaDeAliquotas que possui:
um mtodo aliquota() que, recebe como parmetro o total de rendimentos tributveis de uma
pessoa e devolve um nmero entre 0 e 1.0 correspondente aliquota de imposto que a pessoa
dever pagar e
um mtodo valorADeduzir() que recebe como parmetro o total de rendimentos tributveis de
uma pessoa e devolve o valor a deduzir no clculo do imposto.

40

CAPTULO 7. PROGRAMAS COM VRIOS OBJETOS


Agora escreva uma classe CalculadoraDeImposto que possui um nico mtodo que recebe como parmetro o valor dos rendimentos tributveis de uma pessoa e devolve o valor do imposto a ser pago.
Finalmente, escreva um trecho de cdigo (para ser digitado no interpretador) que define os vrios rendimentos de uma pessoa e calcula o imposto a pagar.
Eis a tabela do IR 2004:
Rendimentos Tributveis
At R$ 12.696
De R$ 12.696,01 a R$ 25.380
acima de R$ 25.380

Alquota

Parcela a deduzir

0.15
0.275

R$ 1.904,40
R$ 5.076,90

2. Suponha que voc tenha as seguintes classes:


class A {
d o u b l e a ( i n t meses , d o u b l e t a x a ) {
r e t u r n ( Math . pow ( ( t a x a + 1 0 0 ) / 1 0 0 , meses ) 1 ) ;
}
}
class B {
f i n a l d o u b l e TAXA = 1 . 2 ;
v o i d b ( d o u b l e v a l o r E m p r e s t a d o , i n t meses ) {
A a = new A ( ) ;
d o u b l e v a l o r D a D i v i d a = v a l o r E m p r e s t a d o + ( a . a ( meses , TAXA) v a l o r E m p r e s t a d o ) ;
System . o u t . p r i n t l n ( " D v i d a de " + v a l o r D a D i v i d a + " r e a l ( i s ) , " +
" c a l c u l a d a com t a x a de " + TAXA + "% ao ms . " ) ;
}
}

(a) O que fazem os mtodos a (da classe A) e b (da classe B)? No precisa entrar em detalhes. DICA:
consulte a pgina http://java.sun.com/j2se/1.4.1/docs/api/java/lang/Math.html
(b) Os nomes a e b (dos mtodos) e A e B (das classes) so pssimos. Por qu? Que nomes voc daria?
Sugira, tambm, outro nome para a varivel objeto (criada no interpretador).
(c) Acrescente alguns comentrios no cdigo do mtodo b.
(d) Seria mais fcil digitar o valor 1.2 quando necessrio, em vez de criar uma constante TAXA e utilizla. Ento, por que isso foi feito? Cite, pelo menos, dois motivos. Se voc no sabe o que uma
constante, imagine que um atributo cujo valor no pode ser alterado.

Captulo 8

Laos e Repeties
Quais novidades veremos nesta aula?
A idia de laos em linguagens de programao
O lao while
O operador que calcula o resto da diviso inteira: %

8.1 Laos em linguagens de programao


Vamos apresentar para vocs um novo conceito fundamental de programao: o lao. Mas o que pode ser isso?
Um nome meio estranho, no? Nada melhor do que um exemplo para explicar.
Vamos voltar ao nosso velho conversor de temperatura. Imagine que voc ganhou uma passagem para Nova
Iorque e que os EUA no esto em guerra com ningum. Voc arruma a mala e se prepara para viagem. Antes
de viajar voc resolve conversar com um amigo que j morou nos EUA. Ele acaba lhe dando uma dica: guarde
uma tabelinha de converso de temperaturas de Fahrenheit para Celsius. Ela ser muito til, por exemplo, para
entender o noticirio e saber o que vestir no dia seguinte. Voc ento se lembra das aulas de MAC-110: voc j
tem um conversor pronto. Basta ento us-lo para montar a tabela. Voc chama ento o DrJava e comea uma
nova seo iterativa.
Welcome to DrJava.
> Conversor4 c = new Conversor4()
> c.fahrenheitParaCelsius(0)
-17.77777777777778
> c.fahrenheitParaCelsius(10)
-12.222222222222221
> c.fahrenheitParaCelsius(20)
-6.666666666666667
> c.fahrenheitParaCelsius(30)
41

42

CAPTULO 8. LAOS E REPETIES

-1.1111111111111112
> c.fahrenheitParaCelsius(40)
4.444444444444445
> c.fahrenheitParaCelsius(50)
10.0
> c.fahrenheitParaCelsius(60)
15.555555555555555
> c.fahrenheitParaCelsius(70)
21.11111111111111
> c.fahrenheitParaCelsius(80)
26.666666666666668
> c.fahrenheitParaCelsius(90)
32.22222222222222
> c.fahrenheitParaCelsius(100)
37.77777777777778
> c.fahrenheitParaCelsius(110)
43.333333333333336
>
Pronto, agora s copiar as linhas acima para um editor de textos, retirar as chamadas ao mtodo
fahrenheitParaCelsius (pois elas confundem) e imprimir a tabela.
Ser que existe algo de especial nas diversas chamadas do mtodo fahrenheitParaCelsius acima? Todas
elas so muito parecidas e fcil adivinhar a prxima se sabemos qual a passada. Ou seja, a lei de formao das
diversas chamadas do mtodo simples e bem conhecida. No seria interessante se fosse possvel escrever um
trecho de cdigo compacto que representasse essa idia? Para isso servem os laos: eles permitem a descrio
de uma seqncia de operaes repetitivas.

8.2 O Lao while


O nosso primeiro lao ser o while, a palavra inglesa para enquanto. Ele permite repetir uma seqncia de
operaes enquanto uma condio se mantiver verdadeira. Mais uma vez, um exemplo a melhor explicao.
Experimente digitar as seguintes linhas de cdigo no painel de interaes do DrJava (lembre-se que para digitarmos as 5 linhas do comando while abaixo, necessrio usarmos Shift+Enter ao invs de apenas Enter no
final das 4 linhas iniciais do while):
Welcome to DrJava.
> int a = 1;
> while (a <= 10)
{
System.out.println("O valor atual de a : " + a);
a = a + 1;
}
o resultado ser o seguinte:

43

8.2. O LAO WHILE


O
O
O
O
O
O
O
O
O
O
>

valor
valor
valor
valor
valor
valor
valor
valor
valor
valor

atual
atual
atual
atual
atual
atual
atual
atual
atual
atual

de
de
de
de
de
de
de
de
de
de

a
a
a
a
a
a
a
a
a
a

:
:
:
:
:
:
:
:
:
:

1
2
3
4
5
6
7
8
9
10

Vamos olhar com calma o cdigo acima. Primeiro criamos uma varivel inteira chamada a. O seu valor
inicial foi definido como 1. A seguir vem a novidade: o lao while. Como dissemos antes, ele faz com
que o cdigo que o segue (e est agrupado usando chaves) seja executado enquanto a condio a <= 10 for
verdadeira. Inicialmente a vale 1, por isto este o primeiro valor impresso. Logo depois de imprimir o valor
de a, o seu valor acrescido de 1, passando a valer 2. Neste momento o grupo de instrues que segue o
while terminou. O que o computador faz voltar linha do while e testar a condio novamente. Como a
agora vale 2, ele ainda menor que 10. Logo as instrues so executadas novamente. Elas sero executadas
enquanto a condio for verdadeira, lembra? Mais uma vez, o valor atual de a impresso e incrementado de 1,
passando a valer 3. De novo o computador volta linha do while, testa a condio (que ainda verdadeira) e
executa as instrues dentro das chaves. Esse processo continua at que o a passe a valer 11, depois do dcimo
incremento. Neste instante, a condio torna-se falsa e na prxima vez que a condio do while testada, o
computador pula as instrues dentro das chaves do while. Ufa, isso! Ainda bem que o computador que
tem todo o trabalho! Uma das principais qualidades do computador a sua capacidade de efetuar repeties.
Ele faz isso de forma automatizada e sem se cansar. O lao uma das formas mais naturais de aproveitarmos
essa caracterstica da mquina.
Agora vamos ver como esse novo conhecimento pode nos ajudar a montar a nossa tabela de converso
de forma mais simples e flexvel. Se pensarmos bem, veremos que as operaes realizadas para calcular as
temperaturas para tabela so semelhantes ao lao apresentado. S que no lugar de simplesmente imprimir os
diferentes valores de uma varivel, para gerar a tabela chamamos o mtodo fahrenheitParaCelsius vrias
vezes. Vamos agora adicionar um mtodo novo classe Conversor4, que ter a funo de imprimir tabelas de
converso para diferentes faixas de temperatura. O cdigo final seria:
c l a s s Conversor5
{
/
C o n v e r t e t e m p e r a t u r a de C e l s i u s p a r a F a h r e n h e i t .
/
double c e l s i u s P a r a F a h r e n h e i t ( double c e l s i u s )
{
return c e l s i u s 9.0 / 5.0 + 32;
}
/
C o n v e r t e t e m p e r a t u r a de F a h r e n h e i t p a r a C e l s i u s .
/
double f a h r e n h e i t P a r a C e l s i u s ( double f a h r )

44

CAPTULO 8. LAOS E REPETIES


{
return ( f a h r 3 2 . 0) 5.0 / 9 . 0 ;
}
/
I m p r i m e uma t a b e l a de c o n v e r s o F a r a n h e i t => C e l s i u s .
/
void i m p r i m e T a b e l a F a h r e n h e i t P a r a C e l s i u s ( double i n i c i o , double fim )
{
double f a h r = i n i c i o ;
double c e l s i u s ;
w h i l e ( f a h r <= f i m )
{
celsius = fahrenheitParaCelsius ( fahr );
System . o u t . p r i n t l n ( f a h r + " F = " + c e l s i u s + "C" ) ;
fahr = fahr + 10.0;
}
}

Muito melhor, no?

8.3

Nmeros primos

Vejamos agora um novo exemplo. Todos devem se lembrar o que um nmero primo: um nmero inteiro que
possui exatamente dois divisores inteiros distintos, o 1 e o prprio nmero. Vamos tentar escrever uma classe
capaz de reconhecer e, futuramente gerar, nmeros primos.
Como podemos reconhecer nmeros primos? A prpria definio nos d um algoritmo. Dado um candidato
a primo x, basta verificar se algum inteiro entre 2 e x - 1 divide x. Ento para verificar se um nmero primo
podemos usar um lao que testa se a diviso exata ocorreu.
Porm, ainda falta um detalhe. Como podemos verificar se uma diviso entre nmeros inteiros exata. J
sabemos que se dividirmos dois nmeros inteiros em Java a resposta inteira. E o resto da diviso? Felizmente,
h um operador especial que devolve o resto da diviso, o operador %. Vejamos alguns exemplos:
Welcome to DrJava.
> 3 / 2
1
> 3 % 2
1
> 5 / 3
1
> 5 % 3
2
> int div = 7 / 5
> int resto = 7 % 5
> div
1

8.4. EXERCCIOS

45

> resto
2
> div*5 + resto
7
>
Deu para pegar a idia, no?
Agora vamos escrever uma classe contendo um mtodo que verifica se um inteiro primo ou no, imprimindo a resposta na tela. O nome que daremos nossa classe GeradorDePrimos. A razo para esse nome
ficar clara na prxima aula.
c l a s s GeradorDePrimos
{
/
I m p r i m e na t e l a s e um nmero i n t e i r o p o s i t i v o p r i m o ou no .
/
void v e r i f i c a P r i m a l i d a d e ( i n t x )
{
/ / Todos o s nmeros i n t e i r o s p o s i t i v o s s o d i v i s v e i s p o r 1 .
i n t numeroDeDivisores = 1;
/ / O p r i m e i r o c a n d i d a t o a d i v i s o r no t r i v i a l o 2 .
int candidatoADivisor = 2;
/ / T e s t a a d i v i s o p o r t o d o s o s nmeros m e n o r e s ou i g u a i s a x .
w h i l e ( c a n d i d a t o A D i v i s o r <= x )
{
i f ( x % c a n d i d a t o A D i v i s o r == 0 )
numeroDeDivisores = numeroDeDivisores + 1;
candidatoADivisor = candidatoADivisor + 1;
}
/ / Imprime a r e s p o s t a .
i f ( n u m e r o D e D i v i s o r e s == 2 )
System . o u t . p r i n t l n ( x + " p r i m o . " ) ;
else
System . o u t . p r i n t l n ( x + " no p r i m o . " ) ;
}
}

8.4

Exerccios

1. Crie uma classe Fatorial com um mtodo calculaFatorial(int x) que calcula o fatorial de x se
este for um nmero inteiro positivo e -1 se x for negativo.
2. Crie uma classe contendo um mtodo que devolve a mdia dos valores 1, 2, 3, ..., N, onde N o valor
absoluto de um nmero fornecido ao mtodo.
3. Adicione as seguintes funcionalidades classe Conversor5 vista neste captulo:

46

CAPTULO 8. LAOS E REPETIES


(a) Crie o mtodo imprimeTabelaCelsiusParaFahrenheit, que converte no sentido oposto do mtodo imprimeTabelaFahrenheitParaCelsius.
(b) Adicione um parmetro aos mtodos acima que permita a impresso de uma tabela com passos
diferentes de 10.0. Ou seja, o passo entre a temperatura atual e a prxima ser dado por esse novo
parmetro.
4. Escreva uma classe Fibonacci, com um mtodo imprimeFibonacciAte50, que imprime os 50 primeiros
nmeros da seqncia de Fibonacci. Seqncia de Fibonacci:
F1 = 1;
F2 = 1;
Fn = F(n-1) + F(n-2), para todo n > 2, n inteiro.
O mtodo deve ento imprimir F1, F2, F3, ..., F49, F50.
5. Abaixo, apresentamos uma pequena variao do mtodo verificaPrimalidade. Ela no funciona corretamente em alguns casos. Voc deve procurar um exemplo no qual esta verso no funciona e explicar
o defeito usando suas prprias palavras. Note que a falha sutil, o que serve como alerta: programar
uma tarefa difcil, na qual pequenos erros podem gerar resultados desastrosos. Toda ateno pouca!
/
I m p r i m e na t e l a s e um nmero i n t e i r o p o s i t i v o p r i m o ou no .
/
void v e r i f i c a P r i m a l i d a d e ( i n t x )
{
/ / Todos o s nmeros i n t e i r o s p o s i t i v o s s o d i v i s v e i s p o r 1 .
i n t numeroDeDivisores = 1;
/ / O p r i m e i r o c a n d i d a t o a d i v i s o r no t r i v i a l o 2 .
int candidatoADivisor = 2;
/ / T e s t a a d i v i s o p o r t o d o s o s nmeros m e n o r e s ou i g u a i s a x .
w h i l e ( c a n d i d a t o A D i v i s o r <= x )
{
candidatoADivisor = candidatoADivisor + 1;
i f ( x % c a n d i d a t o A D i v i s o r == 0 )
numeroDeDivisores = numeroDeDivisores + 1;
}
/ / Imprime a r e s p o s t a .
i f ( n u m e r o D e D i v i s o r e s == 2 )
System . o u t . p r i n t l n ( x + " p r i m o . " ) ;
else
System . o u t . p r i n t l n ( x + " no p r i m o . " ) ;
}

6. O lao no nosso verificaPrimalidade executado mais vezes do que o necessrio. Na verdade poderamos parar assim que candidatoADivisor chegar em x/2 ou mesmo ao chegar na raiz quadrada de x.
Pense como mudar o programa levando em considerao estes novos limitantes.

8.4. EXERCCIOS

47

7. Escreva uma classe Euclides, com um mtodo mdc que recebe dois nmeros inteiros a1 e a2, estritamente
positivos, com a1 >= a2, e devolve o mximo divisor comum entre eles, utilizando o algoritmo de
Euclides.
Breve descrio do algoritmo de Euclides (para maiores detalhes, consulte seu professor de lgebra):
- Dados a1 e a2, com a1 >= a2, quero o m.d.c.(a1, a2).
- Calcule a3 = a1 % a2.
- Se a3 = 0, fim. A soluo a2.
- Calcule a4 = a2 % a3.
- Se a4 = 0, fim. A soluo a3.
- Calcule a5 = a3 % a4.
- ...
Nota importante: o operador binrio % calcula o resto da diviso de n por m, quando utilizado da seguinte
maneira: n % m. Curiosidade: ele tambm funciona com nmeros negativos! Consulte seu professor de
lgebra ;-)

48

CAPTULO 8. LAOS E REPETIES

Captulo 9

Expresses e Variveis Lgicas


Quais novidades veremos nesta aula?
Condies como expresses lgicas
Variveis booleanas
Condies compostas e operadores lgicos: &&, || e !
Precedncia de Operadores

9.1 Condies como expresses


J vimos que em Java, e outras linguagens de programao, as condies exercem um papel fundamental. So
elas que permitem que diferentes aes sejam tomadas de acordo com o contexto. Isso feito atravs dos
comandos if e while.
Mas, o que so condies realmente? Vimos apenas que elas consistem geralmente de comparaes, usando
os operadores ==, >=, <=, >, < e !=, entre variveis e/ou constantes. Uma caracterstica interessante em linguagens de programao que as condies so na verdades expresses que resultam em verdadeiro ou falso.
Vamos ver isso no DrJava:
Welcome to DrJava.
> 2 > 3
false
> 3 > 2
true
> int a = 2
> a == 2
true
> a >= 2
true
49

50

CAPTULO 9. EXPRESSES E VARIVEIS LGICAS

> a < a + 1
true
>
Vejam que cada vez que digitamos uma condio o DrJava responde true (para verdadeiro) ou false (para
falso).
Para entender bem o que ocorre, melhor imaginar que em Java as condies so expresses que resultam
em um dos dois valores lgicos: verdadeiro ou falso. Neste sentido, Java tambm permite o uso de variveis
para guardar os resultados destas contas, como vemos abaixo.
> boolean comp1 = 2 > 3
> comp1
false
> boolean comp2 = a < a + 1
> comp2
true
>
Com isso acabamos de introduzir mais um tipo de variveis, somando-se aos tipos int e double j conhecidos: o tipo boolean, que usado em variveis que visam conter apenas os valores booleanos (verdadeiro
ou falso). Em portugus este tipo de varivel chamada de varivel booleana em homenagem ao matemtico
ingls George Boole (1815-1864).
Agora que comeamos a ver as comparaes como expresses que calculam valores booleanos, tornase mais natural a introduo dos operadores lgicos. Ns todos j estamos bem acostumados a condies
compostas. Algo como eu s vou praia se tiver sol e as ondas estiverem boas. Nesta sentena a conjuo e
une as duas condies em uma nova condio composta que verdadeira somente se as duas condies que a
formam forem verdadeiras.
Em Java o e lgico representado pelo estranho smbolo &&. Ou seja, uma condio do tipo 1 <= a <=
10 seria escrita em Java como a >= 1 && a <= 10. Da mesma forma temos um smbolo para o ou lgico. Ele
o smbolo ||. Isso mesmo, duas barras verticais. Por fim, o smbolo ! antes de uma expresso lgica nega o
seu valor. Por exemplo a condio "a no igual a 0"poderia ser escrita em Java como !(a == 0)1 .
Por fim, podemos montar expresses compostas unindo, atravs dos operadores descritos acima, condies
simples ou respostas de expresses lgicas anteriores que foram armazenadas em variveis boolenas. Mais uma
vez um exemplo vale mais que mil palavras.
Welcome to DrJava.
> (2 > 3) || (2 > 1)
true
> boolean comp1 = 2 > 3
> comp1
false
> comp1 && (5 > 0)
false
1 Da

vem a explicao para o fato do sinal de diferente fazer referncia ao ponto de exclamao.

9.1. CONDIES COMO EXPRESSES


> !(comp1
true
> int a =
> (a > 5)
true
> boolean
> comp2
false
>

51

&& (5 > 0))


10
&& (!comp1)
comp2 = (a > 5) && comp1

Tambm podemos misturar operadores aritmticos e lgicos, sempre que isso faa sentido. Por exemplo
> (a - 10) > 5
false
> a - (10 > 5)
koala.dynamicjava.interpreter.error.ExecutionError: Bad type in subtraction
>
Note que a ltima expresso resultou em um erro. Afinal de contas, ela pede para somar, a uma varivel
inteira, o resultado de uma expresso lgica, misturando tipos. Isto no faria sentido em Java.
Outra coisa que pode ser feita a criao de mtodos que devolvem um resultado lgico. Assim a resposta
dada por esses mtodos pode ser usada em qualquer lugar onde uma condio faa sentido, como um if ou um
while. Por exemplo, se alterarmos o mtodo verificaPrimalidade, dado na aula passada, para devolver a
resposta (se o nmero primo ou no), ao invs de imprimir na tela, teramos o seguinte mtodo Primo:
/
V e r i f i c a s e um nmero i n t e i r o p o s i t i v o p r i m o ou no .
/
b o o l e a n Primo ( i n t x )
{
/ / Todos o s nmeros i n t e i r o s p o s i t i v o s s a o d i v i s v e i s p o r 1 .
i n t nmeroDeDivisores = 1;
/ / O p r i m e i r o c a n d i d a t o a d i v i s o r no t r i v i a l o 2 .
int candidatoADivisor = 2;
/ / T e s t a a d i v i s o p o r t o d o s o s nmeros m e n o r e s ou i g u a i s a x .
w h i l e ( c a n d i d a t o A D i v i s o r <= x )
{
i f ( x % c a n d i d a t o A D i v i s o r == 0 )
nmeroDeDivisores = nmeroDeDivisores + 1;
candidatoADivisor = candidatoADivisor + 1;
}
i f ( n m e r o D e D i v i s o r e s == 2 )
return true ;
else
return f a l s e ;
}

52

CAPTULO 9. EXPRESSES E VARIVEIS LGICAS

9.2 Precedncia
Como acabamos de apresentar vrios operadores novos, devemos estabelecer a precedncia entre eles. Lembre
que j conhecemos as regras de precedncia dos operadores aritmticos h muito tempo. J a precedncia dos
operadores lgicos coisa nova. A tabela abaixo apresenta todos os operadores vistos em aula, listados da
precedncia mais alta (aquilo que deve ser executado antes) mais baixa:
operadores unrios
operadores multiplicativos
operadores aditivos
operadores de comparao
e lgico
ou lgico
atribuio

-!
*/%
+== != > < >= <=
&&
||
=

Entre operadores com mesma precedncia a operaes so computadas da esquerda para a direita.
Note porm que, nos exemplos acima, abusamos dos parnteses mesmo quando, de acordo com a tabela de
precedncia, eles so desnecessrios. Sempre bom usar parnteses no caso de expresses lgicas (ou mistas),
pois a maioria das pessoas no consegue decorar a tabela acima. Assim, mesmo que voc tenha uma tima
memria, o seu cdigo torna-se mais legvel para a maioria dos mortais.

9.3 Exemplos
Primeiro, vamos retomar o mtodo verificaLados da classe TianguloRetangulo3 vista no Captulo 6. Nele,
testamos se no h lado de comprimento nulo. Entretanto, parece mais natural e correto forar todos os lados a
terem comprimento estritamente positivo:
i f ( ( a > 0 ) && ( b > 0 ) && ( c > 0 ) )
{
/ / A q u i vo o s comandos p a r a v e r i f i c a r a c o n d i o p i t a g r i c a .
}

Podemos tambm usar condies compostas para escrever uma verso mais rpida do mtodo
Primo da aula passada.
/
V e r i f i c a s e um nmero i n t e i r o p o s i t i v o p r i m o ou no .
/
b o o l e a n Primo ( i n t x )
{
/ / Todos o s nmeros i n t e i r o s p o s i t i v o s s a o d i v i s v e i s p o r 1 .
i n t nmeroDeDivisores = 1;
/ / O p r i m e i r o c a n d i d a t o a d i v i s o r no t r i v i a l o 2 .
int candidatoADivisor = 2;
/ / T e s t a a d i v i s o p o r t o d o s o s nmeros m e n o r e s ou i g u a i s a x / 2 ou
/ / at encontrar o primeiro divisor .
w h i l e ( ( c a n d i d a t o A D i v i s o r <= x / 2 ) && ( n m e r o D e D i v i s o r e s == 1 ) )

9.3. EXEMPLOS

53

{
i f ( x % c a n d i d a t o A D i v i s o r == 0 )
nmeroDeDivisores = nmeroDeDivisores + 1;
candidatoADivisor = candidatoADivisor + 1;
}
i f ( ( n m e r o D e D i v i s o r e s == 1 ) && ( x ! = 1 ) && ( x ! = 0 ) && ( x ! = 1))
return true ;
else
return f a l s e ;
}

Melhor ainda podemos finalmente escrever a classe GeradorDePrimos de forma completa. O mtodo mais
interessante o prximoPrimo que devolve o primeiro nmero primo maior do que o ltimo gerado. Este
exemplo j bem sofisticado, vocs tero que estud-lo com calma. Uma sugesto: tente enteder o que o
programa faz, um mtodo por vez. O nico mtodo mais complicado o Primo, mas este ns j vimos.
c l a s s GeradorDePrimos
{
/ / L i m i t e i n f e r i o r p a r a b u s c a de um novo p r i m o .
int l i m i t e I n f e r i o r = 1;
/
P e r m i t e mudar o l i m i t e p a r a cmputo do p r x i m o p r i m o .
/
void c a r r e g a L i m i t e I n f e r i o r ( i n t l )
{
limiteInferior = l ;
}
/
V e r i f i c a s e um nmero i n t e i r o p o s i t i v o p r i m o ou no .
/
b o o l e a n Primo ( i n t x )
{
/ / Todos o s nmeros i n t e i r o s p o s i t i v o s s a o d i v i s v e i s p o r 1 .
i n t nmeroDeDivisores = 1;
/ / O p r i m e i r o c a n d i d a t o a d i v i s o r no t r i v i a l o 2 .
int candidatoADivisor = 2;
/ / T e s t a a d i v i s o p o r t o d o s o s nmeros m e n o r e s ou i g u a i s a x / 2 ou
/ / at encontrar o primeiro divisor .
w h i l e ( ( c a n d i d a t o A D i v i s o r <= x / 2 ) && ( n m e r o D e D i v i s o r e s == 1 ) )
{
i f ( x % c a n d i d a t o A D i v i s o r == 0 )
nmeroDeDivisores = nmeroDeDivisores + 1;
candidatoADivisor = candidatoADivisor + 1;
}
i f ( ( n m e r o D e D i v i s o r e s == 1 ) && ( x ! = 1 ) && ( x ! = 0 ) && ( x ! = 1))
return true ;
else
return f a l s e ;
}

54

CAPTULO 9. EXPRESSES E VARIVEIS LGICAS

/
A cada chamada , c a l c u l a um novo p r i m o s e g u i n d o ordem c r e s c e n t e .
/
i n t prximoPrimo ( )
{
/ / Busca o p r i m e i r o p r i m o d e p o i s do l i m i t e .
l i m i t e I n f e r i o r = l i m i t e I n f e r i o r + 1;
w h i l e ( ! Primo ( l i m i t e I n f e r i o r ) )
l i m i t e I n f e r i o r = l i m i t e I n f e r i o r + 1;
return l i m i t e I n f e r i o r ;
}
}

No deixe de brincar um pouco com objetos da classe GeradorDePrimos para enteder melhor como ela
funciona! Agora um desafio para voc: usando o mtodo prximoPrimo, escreva um novo mtodo void
imprimePrimos (int quantidadeDePrimos) que imprime uma dada quantidade de nmeros primos a partir
do limiteInferior. Experimente executar o mtodo passando 50 como parmetro.

9.4

Exerccio:

1. Escreva uma classe TrianguloRetangulo com um mtodo denominado defineLados(float x1, float
x2, float x3 que recebe trs valores e verifica se eles correspondem aos lados de um tringulo retngulo. Em caso afirmativo, o mtodo retorna true, caso contrrio ele retorna false. Note que o programa
deve verificar quais dos trs valores corresponde hipotenusa. Construa duas verses do mtodo, uma
contendo trs ifs e outra contendo apenas um if!
2. Escreva uma classe Brincadeiras que possua 3 atributos inteiros. Escreva um mtodo para carregar
valores nestes atributos e, em seguida, escreva os seguintes mtodos:
(a) troca2Primeiros() que troca os valores dos dois primeiros atributos. Por exemplo, se antes da
chamada do mtodo o valor dos atributos <1, 2, 3>, depois da chamada, eles devero valer <2, 1,
3>.
(b) imprime() que imprime o valor dos 3 atributos.
(c) imprimeEmOrdemCrescente() que imprime o valor dos 3 atributos em ordem crescente.
3. A linguagem Java oferece operadores que, se usados corretamente, ajudam na apresentao e digitao
do cdigo, tornando-o mais enxuto. Veremos neste exerccio dois deles: os operadores de incremento e
de decremento. Verifique o funcionamento desses operadores usando os mtodos da classe abaixo.
class Experincia
{
void verIncremento ( i n t n )
{
int x = n ;
System . o u t . p r i n t l n ( " Nmero i n i c i a l x > " + x ) ;
System . o u t . p r i n t l n ( " x++
> " + x + + ) ;
System . o u t . p r i n t l n ( " Novo v a l o r de x > " + x ) ;

9.4. EXERCCIO:

55

x = n;
System . o u t . p r i n t l n ( " Nmero i n i c i a l x > " + x ) ;
System . o u t . p r i n t l n ( " ++x
> " + ++x ) ;
System . o u t . p r i n t l n ( " Novo v a l o r de x > " + x ) ;
}
void verDecremento ( i n t n )
{
int x = n ;
System . o u t . p r i n t l n ( " Nmero i n i c i a l x > " + x ) ;
System . o u t . p r i n t l n ( " x
> " + x );
System . o u t . p r i n t l n ( " Novo v a l o r de x > " + x ) ;
x = n;
System . o u t . p r i n t l n ( " Nmero i n i c i a l x > " + x ) ;
System . o u t . p r i n t l n ( "x
> " + x ) ;
System . o u t . p r i n t l n ( " Novo v a l o r de x > " + x ) ;
}
}

Entenda bem o cdigo e observe os resultados. Em seguida, tire suas concluses e compare-as com as
concluses de seus colegas.

56

CAPTULO 9. EXPRESSES E VARIVEIS LGICAS

Captulo 10

Mergulhando no while
Quais novidades veremos nesta aula?
Reforo em while
O comando do...while

10.1 Um pouco mais sobre primos.


Vamos iniciar este captulo com dois exerccios. Primeiro, que tal modificarmos o mtodo de gerao de primos
para que ele use o fato de que os nicos candidatos a primos maiores do que 2 so mpares? Uma complicao
interessante que o limiteInferior para o prximo primo pode ser modificado pelo usurio a qualquer
momento chamando carregaLimiteInferior. Isso deve ser contemplado na soluo. Aqui vai a resposta:
/
A cada chamada , c a l c u l a um novo p r i m o s e g u i n d o ordem c r e s c e n t e .
/
i n t prximoPrimo ( )
{
/ / Move o l i m i t e i n f e r i o r na d i r e o do p r x i m o p r i m o .
/ / Temos que c o n s i d e r a r que o l i m i t e i n f e r i o r pode s e r p a r
/ / p o r q u e e l e pode s e r m o d i f i c a d o a q u a l q u e r momento com uma
/ / chamada a c a r r e g a L i m i t e I n f e r i o r .
i f ( l i m i t e I n f e r i o r == 1 )
l i m i t e I n f e r i o r = 2;
e l s e i f ( l i m i t e I n f e r i o r % 2 == 0 )
l i m i t e I n f e r i o r = l i m i t e I n f e r i o r + 1;
else
l i m i t e I n f e r i o r = l i m i t e I n f e r i o r + 2;
/ / Encontra o prximo primo
while ( ! Primo ( l i m i t e I n f e r i o r ) )
l i m i t e I n f e r i o r = l i m i t e I n f e r i o r + 2;

57

58

CAPTULO 10. MERGULHANDO NO WHILE


return l i m i t e I n f e r i o r ;

Nosso prximo desafio criar uma nova classe ManipuladorDeInteiros. Ela deve conter o mtodo
fatoraInteiro que deve imprimir a decomposio em primos de um inteiro positivo maior ou igual a 2. Uma
dica importante usar o GeradorDePrimos Antes de ler soluo colocada abaixo, tente com afinco fazer o
exerccio sozinho.
class ManipuladorDeInteiros {
/
F a t o r a em p r i m o s um i n t e i r o > 1 .
/
void f a t o r a I n t e i r o ( i n t x )
{
System . o u t . p r i n t ( x + " = " ) ;
/ / Usa um g e r a d o r de p r i m o s p a r a e n c o n t r a r o s p r i m o s m e n o r e s ou i g u a i s a x .
G e r a d o r D e P r i m o s g e r a d o r = new G e r a d o r D e P r i m o s ( ) ;
i n t primo = g e r a d o r . prximoPrimo ( ) ;
/ / C o n t i n u a f a t o r a n d o o nmero a t que x t o r n e s e 1 .
while ( x > 1)
{
i f ( x % p r i m o == 0 )
{
System . o u t . p r i n t ( " " + p r i m o ) ;
x = x / primo ;
}
else
primo = g e r a d o r . prximoPrimo ( ) ;
}
/ / I m p r i m e um f i m de l i n h a no f i n a l .
System . o u t . p r i n t l n ( ) ;
}
}

Um exemplo de uso do nosso ManipuladorDeInteiros:


Welcome to DrJava.
> ManipuladorDeInteiros m = new ManipuladorDeInteiros()
> m.fatoraInteiro(5)
5 = 5
> m.fatoraInteiro(10)
10 = 2 5
> m.fatoraInteiro(18)
18 = 2 3 3
> m.fatoraInteiro(123456)
123456 = 2 2 2 2 2 2 3 643
> m.fatoraInteiro(12345678)
12345678 = 2 3 3 47 14593

10.2. UMA BIBLIOTECA DE FUNES MATEMTICAS.

59

> m.fatoraInteiro(167890)
167890 = 2 5 103 163
>
Obs: Note que na soluo usamos uma rotina de impresso nova: System.out.print. Ela muito parecida
com System.out.println com a diferena de que no muda a linha ao terminar de imprimir.

10.2 Uma biblioteca de funes matemticas.


Terminamos com um exerccio clssico. Vamos mostrar como construir uma pequena biblioteca de funes
matemticas avanadas. Com ser que o computador consegue calcular senos, cossenos, logaritmos? O segredo
para implementar essas funes em Java um bom conhecimento de clculo e laos.
Usando clculo, sabemos que essas funes matemticas complicadas possuem expanses de Taylor.
Estas expanses envolvem apenas polinmios que podem ser calculados facilmente usando laos. Pena que
vocs s vo aprender isso na disciplina de Clculo mais para o fim do semestre... De qualquer forma, vejamos
a expanso de algumas dessas funes:
sen(x) =

x
1!

k (2k+1)

x
x3! + x5! ... + (1)
(2k+1)! + ...
2

k (2k)

x
cos(x) = 1 x2! + x4! x6! + ... + (1)
(2k)!
2

+ ...

(k1) xk

ln(1 + x) = x x2 + x3 x4 + ... + (1) k

+ ...

Isso funciona bem sempre que |x| < 1.


O segredo para usar essas frmulas no computador continuar somando at que o mdulo do prximo
termo seja muito pequeno e por isso possa ser desprezado.
Antes de apresentarmos aqui a soluo que consideramos ideal, faa com cuidado e ateno os exerccios
1 (implementao das funes double pot(double x, int y) e int fat(int x)) e 2 (implementao da
funo double sen (double x) usando as funes do exerccio 1.
Agora, aps termos feito, os exerccios 1 e 2, iremos criar uma nova classe, que chamaremos Matemtica,
com mtodos para calcular funes como as apresentadas acima. Abaixo vemos a classe com uma funo que
calcula sen(x) implementada. Compare esta forma de implementar com as formas usadas no exerccio. Qual
mais rpida? Qual mais fcil de entender?
c l a s s Matemtica
{
/ / C o n t r o l a o s i g n i f i c a d o de " p e q u e n o " .
d o u b l e e p s i l o n = 1 . 0 e 8;
double sen ( double x )
{
int k = 1;
double termo = x ;
double seno = termo ;
while ( termo termo > e p s i l o n e p s i l o n )
{

60

CAPTULO 10. MERGULHANDO NO WHILE


/ / muito mais f c i l c o n s t r u i r o prximo termo usando o a n t e r i o r .
k = k + 2;
t e r m o = t e r m o x x / ( k 1 ) / k ;
seno = seno + termo ;
}
return seno ;
}

Um exemplo de uso:
Welcome to DrJava.
> m = new Matemtica();
> m.sen(0.3)
0.2955202066613839
> m.sen(0.5)
0.4794255386164159
> m.sen(3.141596/2.0)
0.9999999999925767
>

10.3

do...while

Para complementar os laos possveis em Java, vejamos uma pequena variao do while. Nele a condio
testada sempre antes de execuo do corpo de comandos que compe o lao. J o lao do...while tem a
condio testada apenas no final. Conseqentemente, no caso do do...while, existe a garantia que o contedo
no interior do lao ser executado pelo menos uma vez, enquanto no while este pode nunca ser executado. Na
prtica, a existncia destes dois tipos de laos uma mera conveniencia sinttica, j que um pode ser facilmente
substitudo pelo outro.
Vejamos um exemplo de utilizao do do...while:
int f a t o r i a l ( int x)
{
int resultado = 1;
do
{
resultado = resultado x;
x = x 1;
} while ( x > 1)
return r e s u l t a d o ;
}

10.4

Exerccios

1. Implementar na classe Matemtica as funes double pot(double x, int y) que calcula xy e int
fat(int x) que calcula x!.

10.4. EXERCCIOS

61

2. Implementar na classe Matemtica a funo double sen (double x) utilizando-se das funes double
pot(double x, int y) e int fat(int x) do item anterior.
3. Implementar na classe Matemtica funes para calcular cos(x) e ln(1 + x). Note que para implementar
o ln(1 + x) deve-se criar uma funo double ln(double x) e no interior da funo definir uma varivel
local x2 = 1 - x de modo que se possa calcular ln(1 + x2).
4. O enunciado deste exerccio bem mais complexo que a soluo, por isso no tenha medo! Imagine um
quadrado em um plano e uma reta paralela a um dos lados do quadrado: a projeo do quadrado sobre a
reta tem exatamente o mesmo comprimento que o lado do quadrado. Imagine agora que este quadrado
seja girado sobre o plano; a projeo do quadrado sobre a reta tem um novo tamanho. Crie uma classe
Projetor que possua um mtodo gira que aceite como parmetro o nmero de graus que o quadrado deve
girar em relao sua posio anterior e imprima na tela o tamanho da projeo do quadrado sobre a
reta. Note que se o usurio executar o mtodo duas vezes, com os parmetros 22 e 35, sua classe
deve responder qual o tamanho da projeo para inclinaes do quadrado de 22 e 57 graus.
Escreva 3 solues para este exerccio: uma que voc considere elegante e clara, uma com um
nico mtodo e uma com o mximo nmero possvel de mtodos. Utilize os mtodos sen() e
cos() desenvolvidos neste captulo.
Utilize agora os mtodos java.lang.Math.cos() e java.lang.Math.sin() disponveis na biblioteca Java, que calculam, respectivamente, o coseno e o seno do ngulo passado como parmetro
em radianos (graus * PI/180 = radianos). Compare os resultados com os obtidos com nossas implementaes de sen() e cos().

62

CAPTULO 10. MERGULHANDO NO WHILE

Captulo 11

Caracteres e cadeias de caracteres


Quais novidades veremos nesta aula?
Introduo do tipo char
Uma classe pronta: String

11.1 Um tipo para representar caracteres


At hoje j vimos diferentes tipos de variveis, vimos os inteiros (int) e os reais (double). Alm disto, tambm
vimos as variveis booleanas, que podem ter apenas dois valores, verdadeiro, ou falso (boolean). Parece
intuitivo que as linguagens de programao tambm ofeream variveis para a manipulao de caracteres. No
caso de Java temos o tipo char. Vejamos um exemplo de uso:
class Caracter1
{
v o i d v e r i f i c a R e s p o s t a ( char ch )
{
i f ( ( ch == s ) | | ( ch == S ) )
System . o u t . p r i n t l n ( "A r e s p o s t a f o i sim " ) ;
e l s e i f ( ( ch == n ) | | ( ch == N ) )
System . o u t . p r i n t l n ( "A r e s p o s t a f o i no " ) ;
else
System . o u t . p r i n t l n ( " R e s p o s t a i n v l i d a " ) ;
}
}

No exemplo acima podemos ver que para se representar um caracter usamos aspas simples (). Tambm
podemos ver que os caracteres minsculos so diferentes do mesmo caracter maisculo.
Um outro exemplo um pouco mais elaborado pode ser visto abaixo:
class Caracteres
{
v o i d i m p r i m e C a r a c t e r e s ( char ch , i n t n )

63

64

CAPTULO 11. CARACTERES E CADEIAS DE CARACTERES


{
int i = 0;
while ( i < n )
{
System . o u t . p r i n t ( ch ) ;
i = i + 1;
}
}

Neste exemplo, so impressos diversos caracteres do mesmo tipo. Observe abaixo como podemos adicionar
um novo mtodo para desenhar letras grandes:
class Caracteres
{
v o i d i m p r i m e C a r a c t e r e s ( char ch , i n t n )
{
int i = 0;
while ( i < n )
{
System . o u t . p r i n t ( ch ) ;
i = i + 1;
}
}
void novaLinha ( )
{
System . o u t . p r i n t l n ( ) ;
}
v o i d i m p r i m e C a r a c t e r e s N L ( char ch , i n t n )
{
i m p r i m e C a r a c t e r e s ( ch , n ) ;
novaLinha ( ) ;
}
void desenhaE ( )
{
imprimeCaracteresNL ( , 2 0 ) ;
i m p r i m e C a r a c t e r e s N L ( E , 1 5 ) ;
i m p r i m e C a r a c t e r e s N L ( E , 1 4 ) ;
i m p r i m e C a r a c t e r e s N L ( E , 3 ) ;
i m p r i m e C a r a c t e r e s N L ( E , 3 ) ;
i m p r i m e C a r a c t e r e s N L ( E , 1 3 ) ;
i m p r i m e C a r a c t e r e s N L ( E , 1 3 ) ;
i m p r i m e C a r a c t e r e s N L ( E , 3 ) ;
i m p r i m e C a r a c t e r e s N L ( E , 3 ) ;
i m p r i m e C a r a c t e r e s N L ( E , 1 4 ) ;
i m p r i m e C a r a c t e r e s N L ( E , 1 5 ) ;
imprimeCaracteresNL ( , 2 0 ) ;
}
}

A sada do programa :
********************

11.2. CADEIAS DE CARACTERES (STRING)

65

EEEEEEEEEEEEEEE
EEEEEEEEEEEEEE
EEE
EEE
EEEEEEEEEEEEE
EEEEEEEEEEEEE
EEE
EEE
EEEEEEEEEEEEEE
EEEEEEEEEEEEEEE
*********************
Os diferentes mtodos que imprimem caracteres pulando, ou sem pular linha sero usados para desenhar
letras onde necessrio intercalar espaos e letras. Como por exemplo para a letra U. Onde a primeira linha
deve ser impressa como:
i m p r i m e C a r a c t e r e s ( U , 3 ) ;
imprimeCaracteres ( , 9);
i m p r i m e C a r a c t e r e s ( U" , 3 ) ;

11.2

/ / e s p a o tambm um c a r a c t e r e

Cadeias de Caracteres (String)

Uma forma de escrevermos palavras no computador seria usando grupos de caracteres, entretanto isto depende
de um conceito mais avanado que ainda no vimos. A nossa outra opo usar uma classe pronta, que j vem
com a linguagem Java, a classe String.
Nos nossos primeiros exemplos ns j havamos feito algumas operaes com strings. Como por exemplo:
System . o u t . p r i n t l n ( "O t r i n g u l o r e t n g u l o " ) ;
System . o u t . p r i n t l n ( "A r a i z de " + 4 + " i g u a l a " + 2 + " . " ) ;

Agora ns veremos com mais detalhes esta classe String . Podemos ver que o operador "+"tem um
significado natural o de concatenao. Logo, as seguintes operaes so vlidas:
S t r i n g a = " abc " ;
String b = " cdf " ;
String c ;
c = a + b;
System . o u t . p r i n t l n ( c ) ;

Podemos tambm concatenar a uma String nmeros:


S t r i n g a = "O r e s u l t a d o " ;
int i = 10;
String c ;
c = a + i;
System . o u t . p r i n t l n ( c ) ;

Alm disto, existem alguns mtodos pr-definidos na classe String. Entre eles podemos citar:

66

CAPTULO 11. CARACTERES E CADEIAS DE CARACTERES


char charAt(int index) - devolve o caracter na posio i.
Os ndices em uma string vo de zero ao seu tamanho menos um. Exemplo:
S t r i n g s = " mesa " ;
System . o u t . p r i n t l n ( s . c h a r A t ( 0 ) ) ;
System . o u t . p r i n t l n ( s . c h a r A t ( 3 ) ) ;

/ / Imprime
/ / Imprime

m
a

int compareTo(String outra) - compara duas Strings.


Devolve um nmero positivo se a outra for menor, 0 se forem iguais, e um negativo caso contrrio.
Exemplo:
S t r i n g s 1 = " mesa " ;
S t r i n g s2 = " c a d e i r a " ;
System . o u t . p r i n t l n ( s 1 . compareTo ( s 2 ) ) ;

/ / i m p r i m e 10

boolean endsWith(String suffix) - verifica se a string acaba com o sufixo dado.


int indexOf(char ch) - devolve o ndice da primeira ocorrncia de ch na string. Exemplo:
S t r i n g s 1 = " mesa " ;
System . o u t . p r i n t l n ( s 1 . i n d e x O f ( a ) ) ;
System . o u t . p r i n t l n ( s 1 . i n d e x O f ( x ) ) ;

/ / imprime 3
/ / i m p r i m e 1

int length() - devolve o tamanho da string. Exemplo:


S t r i n g s 1 = " mesa " ;
System . o u t . p r i n t l n ( s 1 . l e n g h t h ( ) ) ;

/ / imprime 4

String toUpperCase() - devolve a string convertida para letras maisculas. Exemplo:


S t r i n g s 1 = " mesa " ;
System . o u t . p r i n t l n ( s 1 . t o U p p e r C a s e ( ) ) ;

11.3

/ / i m p r i m e MESA

Exerccios:

1. Escreva uma classe Linha que possua um mtodo imprimeLinha que, ao ser evocado, imprime uma
linha de caracteres "X"na diagonal na tela de interaes do DrJava. Use laos while! DICA: voc vai
precisar do mtodo System.out.print(), que imprime seu argumento na tela mas no passa para a
linha seguinte; imprima linhas com nmero crescente de espaos no comeo e o caracter "X"no final.
2. Escrever um mtodo que retorna o nmero ocorrncias da vogal a em uma frase contida em uma String.
3. Implemente um mtodo que determina a freqncia relativa de vogais em uma String. Considere as
letras maisculas e minsculas no acentuadas.

Captulo 12

Manipulando nmeros utilizando diferentes


bases
Quais novidades veremos nesta aula?
Como extrair os dgitos de um nmero
Como converter nmeros de uma base para outra

Aqui deve ser colocada uma explicao sobre converso de bases e como extrair os dgitos de um nmero.
Exemplos:
1. Imprimir um nmero natural dgito por dgito.
2. Dado um nmero natural n, na base binria, convert-lo para a base decimal. Exemplo: Dado 10010 a
sada deve ser 18 pois: 1 24 + 0 23 + 0 22 + 1 21 + 0 20 = 18.
c l a s s Conversao
{
int binarioDecimal ( int n)
{
i n t dec = 0 ;
int pot2 = 1;
while ( n != 0){
/ p r o c e s s a um d g i t o b i n r i o /
d e c = d e c + n % 10 p o t 2 ;
n = n / 10;
pot2 = pot2 2;
}
return dec ;
}
int decimalBinario ( int n)
{

67

68

CAPTULO 12. MANIPULANDO NMEROS UTILIZANDO DIFERENTES BASES


int dig ;
int bin = 0;
int pot = 1;
while ( n > 0) {
/ p r x i m o d g i t o b i n r i o menos s i g n i f i c a t i v o /
dig = n % 2;
/ remove e s s e d g i t o do que r e s t a /
n = n / 2;
/ a d i c i o n a o d i g i t o como o m a i s s i g n i f i c a t i v o /
bin = bin + dig pot ;
pot = pot 10;
}
return bin ;
}
}

12.1

Exerccios

1. Dado um nmero natural n, contar quantos dgitos ele tem. No esquea de considerar o caso do nmero
ser igual a zero!
2. Dado um nmero verificar se o mesmo possui dois dgitos consecutivos iguais. Para resolver este problema podemos usar um tcnica denominada indicador de passagem, para isto, inicialmente vamos supor
que o nmero no contm dgitos iguais. Verificaremos cada par de dgitos consecutivos, caso algum
deles seja igual saberemos que ele contm dgitos consecutivos iguais. Em outras palavras, vamos inicializar uma varivel booleana com falso, vamos testar a condio para todos os dgitos consecutivos, se
forem iguais mudamos a condio. Ao final, a resposta vai corresponder ao estado final desta condio.
3. Dado um nmero natural n, verificar se n , ou no palndromo. Um nmero palndromo um nmero
que lido de trs para frente o mesmo nmero de quando lido normalmente, por exemplo:

78087
1221
11111
3456 no palindromo!!!

Duas maneiras de se resolver estes problemas so apresentadas abaixo. Escreva as solues para cada
uma delas.
A forma mais fcil construir o nmero inverso e compar-lo com o original.
A outra soluo consiste em supor inicialmente que o nmero palndromo, e em seguida verificar
se a condio de igualdade vlida para os extremos.
Se o nmero for negativo, considere apenas o seu valor absoluto (isso apenas uma conveno nossa
para este exerccio). Por exemplo, -2002 deve ser considerado palndromo.
Curiosidade: nmeros palndromos tambm so conhecidos por capicuas.

12.1. EXERCCIOS

69

4. Uma propriedade de nmeros naturais a seguinte: um nmero sempre maior do que o produto dos
seus dgitos. Faa uma classe com dois mtodos: int calculaProd(int n), que calcula o produto
dos dgitos de um nmero natural n, e boolean verificaProp(int n), que verifica se a propriedade
valida para um nmero n dado.
5. Crie mtodos para converter uma String contendo um nmero em algarismo romanos em um inteiro e
vice-versa.
6. Crie uma classe contendo um mtodo que recebe um inteiro e o imprime representado em notao cientfica. Por exemplo,
> Inteiro i = new Inteiro();
> i.carregaValor(1356);
> i.imprimeEmNotacaoCientifica();
1,356e3
> i.carregaValor(-102);
> i.imprimeEmNotacaoCientifica();
-1,02e2
> i.carregaValor(7);
> i.imprimeEmNotacaoCientifica();
7,0e0
> i.carregaValor(900200);
> i.imprimeEmNotacaoCientifica();
9,002e5
7. Implemente a operao de diviso de dois nmeros inteiros utilizando apenas laos e os operadores +, e %.

70

CAPTULO 12. MANIPULANDO NMEROS UTILIZANDO DIFERENTES BASES

Captulo 13

Arrays (vetores)
Quais novidades veremos nesta aula?
arrays (vetores)
programas independentes em Java (mtodo main)

13.1

Arrays (vetores)

Muitas vezes, precisamos que um objeto guarde um grande nmero de informaes. Por exemplo, se precisamos calcular a temperatura mdia em um dado ms poderamos ter uma classe similar seguinte:
c l a s s TemperaturasDoMes
{
double t1 , t2 , t3 , t4 , t5 , t6 , t7 , t8 , t9 , t10 , t11 , t12
t13 , t14 , t15 , t16 , t17 , t18 , t19 , t20 , t21 , t22 , t23 ,
t24 , t25 , t26 , t27 , t28 , t29 , t30 , t31 ;
/ / etc .
}

onde cada varivel guarda a temperatura mdia de um dia do ms. Isso claramente indesejvel. Imagine
ainda se quisssemos uma classe para guardar as temperaturas mdias de todos os dias do ano. Precisaramos
de 365 variveis? Felizmente no!
A linguagem Java possui o conceito de array que uma estrutura de dados que permite guardar uma
seqncia de valores (nmeros, caracteres, ou objetos quaisquer) de uma forma nica e organizada. Utilizando
um array, a classe anterior ficaria assim:
c l a s s TemperaturasDoMes
{
d o u b l e [ ] t e m p e r a t u r a s = new d o u b l e [ 3 1 ] ;
/ / etc .
}

71

72

CAPTULO 13. ARRAYS (VETORES)

Note que, no exemplo acima, a linha que define o array temperaturas faz duas coisas simulataneamente
e que podem ser separadas em dois passos:
double[] temperaturas; define um novo array chamado temperaturas e que ir conter valores do tipo
double.
Por enquanto, o array est vazio. Mas quando fazemos temperaturas = new double[31]; estamos
especificando que o array guardar exatamente 31 valores do tipo double. Neste instante, o ambiente Java
reserva a memria necessria para guardar estes 31 valores.
Nota Lingustica: a traduo padro de array para o portugus vetor. No entanto, a
linguagem Java contm um tipo de objeto chamado Vector que semelhante a arrays,
mas no igual. Para evitar confuses entre arrays e Vectors, preferimos no traduzir a
palavra array para vetor neste livro.

Vejamos agora um exemplo simples de utilizao de arrays.


class BrincadeirasComArrays
{
S t r i n g [ ] diasDaSemana = new S t r i n g [ 7 ] ;
i n t [ ] q u a d r a d o s = new i n t [ 1 0 ] ;
void defineDiasDaSemana ( )
{
diasDaSemana [ 0 ] = " domingo " ;
diasDaSemana [ 1 ] = " s e g u n d a f e i r a " ;
diasDaSemana [ 2 ] = " t e r a f e i r a " ;
diasDaSemana [ 3 ] = " q u a r t a f e i r a " ;
diasDaSemana [ 4 ] = " q u i n t a f e i r a " ;
diasDaSemana [ 5 ] = " s e x t a f e i r a " ;
diasDaSemana [ 6 ] = " s b a d o " ;
}
void calculaQuadrados ( )
{
int i = 0;
while ( i < 10)
{
quadrados [ i ] = i i ;
i ++;
}
}
void listaDiasDaSemana ( )
{
int i = 0;
while ( i < 7)
{
System . o u t . p r i n t l n ( diasDaSemana [ i ] ) ;
i ++;
}
}

13.2. CRIAO DE PROGRAMAS JAVA

73

void l i s t a Q u a d r a d o s ( )
{
int i = 0;
while ( i < 10)
{
System . o u t . p r i n t l n ( i + " ao q u a d r a d o " + q u a d r a d o s [ i ] ) ;
i ++;
}
}
}

13.1.1

O atributo length

Arrays so na verdade um tipo especial de objeto em Java. Qualquer array j vem com um atributo pr-definido,
chamado length e que contm o comprimento do array. Desta forma, o mtodo calculaQuadrados acima
poderia ser re-escrito para
void calculaQuadrados ( )
{
int i = 0;
while ( i < quadrados . l e n g t h )
{
quadrados [ i ] = i i ;
i ++;
}
}

O valor do atributo length definido automaticamente pelo ambiente Java, o programador no pode alterlo. Assim, quadrados.length = 2 uma operao ilegal.

13.1.2

Inicializao de arrays

Existe tambm a opo de inicializar um array no momento em que ela declarada. Assim, podemos inicializar
arrays de inteiros e de Strings conforme o exemplo a seguir:
i n t [ ] primos = {2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 , 23};
S t r i n g [ ] p l a n e t a s = { " M e r c r i o " , " Vnus " , " T e r r a " , " M a r t e " , " J u p i t e r " , " S a t u r n o " ,
" Urano " , " Netuno " , " P l u t o " } ;

13.2

Criao de Programas Java

At esta aula, todos os exemplos de cdigos que vimos, a rigor, no eram "programas", eles eram apenas classes
Java que podiam ser usadas dentro do interpretador do DrJava. Mas, e se ns quisssemos criar um programa
para ser utilizado por algum que no possui o DrJava em sua mquina. Neste caso, precisamos criar um
programa a ser executado ou na linha de comando do sistema operacional ou dando-se um "clique duplo"com
o mouse em cima do cone do programa. Para fazer isso, basta que a classe principal do programa possua um
mtodo main como no exemplo a seguir.

74

CAPTULO 13. ARRAYS (VETORES)

class BrincadeirasComArrays
{
/ / a q u i vo o s d e m a i s m t o d o s e a t r i b u t o s da c l a s s e
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g )
{
B r i n c a d e i r a s C o m A r r a y s b = new B r i n c a d e i r a s C o m A r r a y s ( ) ;
b . defineDiasDaSemana ( ) ;
b . calculaQuadrados ( ) ;
b . listaDiasDaSemana ( ) ;
b . listaQuadrados ( ) ;
b . imprimeArray ( arg ) ;
}
void imprimeArray ( S t r i n g [ ] a r r a y )
{
int i = 0;
while ( i < a r r a y . l e n g t h )
{
System . o u t . p r i n t l n ( a r r a y [ i ] ) ;
i ++;
}
}
}

Para executar o seu programa aps compilar a classe, basta abrir um shell (um interpretador de comandos
do sistema operacional; no unix pode ser, por exemplo, o bash; no windows pode ser, por exemplo, o command)
e digitar
java BrincadeirasComArrays um dois trs
java o nome do interpretador Java BrincadeirasComArrays o nome da classe que ser carregada
e cujo mtodo main ser executado. um dois trs so apenas um exemplo de 3 argumentos que estamos
passando, poderia ser qualquer outra coisa.
Neste exemplo, o programa BrincadeirasComArrays geraria a seguinte sada:
domingo
segunda-feira
tera-feira
quarta-feira
quinta-feira
sexta-feira
sbado
0 ao quadrado
1 ao quadrado
2 ao quadrado
3 ao quadrado
4 ao quadrado
5 ao quadrado

0
1
4
9
16
25

13.3. EXERCCIOS
6 ao
7 ao
8 ao
9 ao
um
dois
trs

quadrado
quadrado
quadrado
quadrado

75

36
49
64
81

portanto, para que uma classe possa ser executada a partir da linha de comando do sistema, necessrio
que ele possua um mtodo com a seguinte assinatura:
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g )

o nome do parmetro no precisa ser exatamente arg, qualquer nome funciona; mas o seu tipo tem que ser
obrigatoriamente um array de Strings.

13.3 Exerccios
1. Escreva uma classe Simples contendo um mtodo que recebe um array de inteiros como parmetro e
que inicializa todos os elementos do array com um valor, tambm dado como parmetro. O mtodo deve
devolver o tamanho do array. A assinatura do mtodo deve ser a seguinte:
int inicializaArray ( int [] a , int v );

Escreva agora um mtodo que recebe um array de inteiros como parmetro e imprime o seu contedo:
void imprimeArray ( i n t [ ] a ) ;

Crie agora um mtodo que dado um inteiro verifica se ele esta presente no array.
boolean estaNoArray ( i n t [ ] v , i n t j ) ;

Finalmente, escreva um programa que cria um array, cria um objeto Simples e chama os seus trs
mtodos.
2. Crie um mtodo double[] frequenciaRelativa(int[] v, int n) que recebe um vetor contendo
nmeros inteiros no intervalo [0, n] e devolve um vetor contendo a frequncia relativa de cada um destes
nmeros.
3. Crie um mtodo que, dados dois vetores a e b, verifica se o vetor de menor tamanho uma subsequncia
do vetor de tamanho maior.
Ex: O vetor [9, 5] uma subsequncia de [3, 9, 5, 4, -1].
4. Crie uma classe contendo um mtodo que, dado um vetor v de inteiros, imprime o segmento de soma
mxima.
Ex: No vetor [ 1, 5, -4, 7, 2, -3] o segmento de soma mxima [ 7, 2]

76

CAPTULO 13. ARRAYS (VETORES)

Captulo 14

for, leitura do teclado e converso de Strings


Quais novidades veremos nesta aula?
for (mais um comando de repetio)
Leitura de dados do teclado (classe SavitchIn)
Converso de Strings para nmeros

14.1 O comando for


Voc deve ter notado que quando implementamos laos com o comando while, muito comum que sigamos
um padro bem definido. Considere os dois exemplos a seguir que vimos na aula passada:
void listaDiasDaSemana ( )
{
int i = 0;
while ( i < 7)
{
System . o u t . p r i n t l n ( diasDaSemana [ i ] ) ;
i ++;
}
}
void calculaQuadrados ( )
{
int i = 0;
while ( i < quadrados . l e n g t h )
{
quadrados [ i ] = i i ;
i ++;
}
}

Em ambos os casos, a estrutura do lao a seguinte:


77

78

CAPTULO 14. FOR, LEITURA DO TECLADO E CONVERSO DE STRINGS


i n t i = 0 ; / / d e f i n e onde o l a o s e i n i c i a

/ / d e f i n e o c r i t r i o p a r a c o n t i n u a r m o s d e n t r o do l a o
while ( i < quadrados . l e n g t h )
{
quadrados [ i ] = i i ; / / a operao propriamente d i t a
i ++;
/ / comando de a t u a l i z a o p a r a p a s s a r m o s p a r a a p r x i m a i t e r a o
}

Ou seja, um formato genrico para laos com while seria o seguinte:


inicializao ;
while ( condio para c o n t i n u a r )
{
comando ;
atualizao ;
}

Aps muito observar este padro, projetistas de linguagens de programao decidiram criar um novo comando para implementao de laos onde todas estas partes relacionadas ao lao fossem organizadas de uma
forma melhor. Assim, surgiu o comando for que, nas linguagens C, C++ e Java, adquirem o seguinte formato:
for ( i n i c i a l i z a o ; condio para continuar ; a t u a l i z a o )
{
comando ;
}

onde as chaves so apenas necessrias se comando for composto. Com o for, podemos implementar
exatamente o mesmo que com o while mas, no caso do for, todas as operaes relacionadas ao lao ficam na
mesma linha o que facilita a visualizao e o entendimento de quem olha para o cdigo.

14.2 Leitura do Teclado


Na aula passada, aprendemos como escrever um programa em Java que pode ser executado a partir da linha de
comando, sem a necessidade de utilizar um ambiente como o DrJava para execut-lo. Aprendemos tambm a
receber dados como parmetro atravs da linha de comando utilizando o parmetro args do mtodo main. No
entanto, existem casos em que gostaramos de ler valores digitados pelo usurio atravs do teclado durante a
execuo do programa. Java oferece algumas formas de se fazer isso mas nenhuma delas muito simples. Para
facilitar a vida de iniciantes em programao Java, podemos utilizar uma classe que esconde as partes mais
complicadas da leitura atravs do teclado. Neste livro utilizaremos a classe SavitchIn escrita pelo Prof. Walter
Savitch da Universidade da California em San Diego.
Em seus EPs e exerccios, para usar a classe SavitchIn, voc pode baix-la do stio do Prof. Savitch 1 .
Aps compilar o SavitchIn.java para produzir o SavitchIn.class, basta copi-lo para o mesmo diretrio
onde os seus arquivos .class sero guardados para que voc possa utilizar os mtodos da classe SacitchIn. Uma
descrio detalhada de todos os mtodos da SavitchIn est disponvel na Web2 . Mas, em MAC 110, ns vamos
nos concentrar apenas nos seguintes mtodos:
1 http://www.cs.ucsd.edu/users/savitch/java/SavitchIn.txt
2 http://www.sinc.sunysb.edu/Stu/fmquresh/SavitchIn.html

14.3. CONVERSO DE STRING PARA NMEROS

79

public class SavitchIn


{
public s t a t i c String readLine ( ) ;
p u b l i c s t a t i c i n t r e a d L i n e I n t ( ) ; / / s u p e que h a p e n a s um i n t e i r o
na l i n h a
p u b l i c s t a t i c d o u b l e r e a d L i n e D o u b l e ( ) ; / / a p e n a s um d o u b l e na l i n h a
/
I n t h e f o l l o w i n g method
I f t h e i n p u t word i s " t r u e " o r " t " , t h e n t r u e i s r e t u r n e d .
I f t h e i n p u t word i s " f a l s e " o r " f " , t h e n f a l s e i s r e t u r n e d .
U p p e r c a s e and l o w e r c a s e l e t t e r s a r e c o n s i d e r e d e q u a l . I f t h e
u s e r e n t e r s a n y t h i n g e l s e ( e . g . , m u l t i p l e words o r d i f f e r e n t
words ) , t h e n t h e u s e r i s a s k e d t o r e e n t e r t h e i n p u t .
/
public s t a t i c boolean readLineBoolean ( ) ;
}

A palavra static na declarao de cada mtodo indica que este mtodo pode ser utilizado mesmo que no
existam instncias da classe. Para utiliz-lo basta fazer algo como no exemplo seguinte:
f o r ( i = 1 ; i <= 1 0 ; i ++)
{
i n t num = S a v i t c h I n . r e a d L i n e I n t ( ) ;
System . o u t . p r i n t l n ( i + " o nmero d i g i t a d o : " + num ) ;
}

Nota: Por uma limitao do DrJava, a classe SavitchIn ainda no funciona na janela Interactions. Segundo
os desenvolvedores do DrJava, esta limitao ser solucionada no futuro. Portanto, por enquanto, voc deve
utilizar a SavitchIn em programas a serem executados na linha de comando.

14.3

Converso de String para nmeros

Voc deve ter notado que o mtodo main recebe sempre Strings como parmetro. Mas e se quisermos receber
valores numricos? Neste caso temos que converter o String que recebemos em um nmero. Isso pode ser feito
atravs da classe Integer ou da classe Double que contm mtodos para efetuar estas converses:
S t r i n g m e u S t r i n g I n t e i r o = " 10 " ;
int meuInteiro = Integer . parseInt ( meuStringInteiro ) ;
S t r i n g meuStringReal = " 3.14159265 " ;
d o u b l e meuReal = Double . p a r s e D o u b l e ( m e u S t r i n g R e a l ) ;

14.4 Exerccios
1. Escreva um mtodo que recebe um array de doubles como parmetro e imprime o seu contedo.
2. Escreva um mtodo somaArrays que recebe 3 arrays de mesmo comprimento como parmetro e que
calcula a soma dos dois primeiros e a armazena no terceiro. A soma deve ser implementada como
soma vetorial, ou seja soma-se a primeira posio de um vetor com a primeira posio do segundo,
armazenando-se o resultado na primeira posio do terceiro e assim por diante. Nota: o terceiro array

80

CAPTULO 14. FOR, LEITURA DO TECLADO E CONVERSO DE STRINGS


que passado como parmetro chamado de parmetro de sada. Quando o mtodo se inicia, ele j
contm um array que passado por quem o, mas o contedo deste array no relevante. O mtodo
preenche esse array com valores e estes valores podero ser acessados aps o retorno do mtodo por
quem o chamou. Isso funciona em Java apenas quando passamos objetos como parmetro (e array um
objeto). Quando passamos tipos bsicos, como int, isso no funciona, ou seja, o valor modificado pelo
mtodo no visvel a quem o chamou.
3. Escreva um mtodo que recebe um array de doubles como parmetro e imprime a mdia dos valores
nele contidos.
4. Escreva dois mtodos (min e max) que recebem um array de inteiros como parmetro e devolvem, respectivamente, um inteiro correspondente ao menor e ao maior elemento do array.
5. Escreva uma classe ProdutoEscalar contendo os seguintes mtodos:
(a) mtodo que recebe um array "vazio"como parmetro e que l valores double do teclado para serem
inseridos no array.
(b) mtodo que recebe 2 arrays de double como parmetro e devolve o produto vetorial (soma dos
produtos das posies de mesmo ndice dos dois arrays).
(c) mtodo main que, usando os mtodos anteriores, l do teclado o comprimento dos vetores, l do teclado o contedo de dois vetores com o tamanho comprimento, calcula o produto vetorial e imprime
o resultado.

Captulo 15

Laos Encaixados e Matrizes


Quais novidades veremos nesta aula?
repeties encaixadas
matrizes (arrays multi-dimensionais)

15.1 Laos encaixados


Em algumas situaes, pode ser necessrio implementar um lao dentro de outro lao. Chamamos esta construo de laos encaixados ou laos aninhados. Eis um exemplo bem simples:
int i , j ;
f o r ( i = 0 ; i < 5 ; i ++)
f o r ( j = 0 ; j < 3 ; j ++)
System . o u t . p r i n t l n ( " i = " + i + " , j = " + j ) ;

A idia que para cada iterao do for mais externo, o interpretador Java executa o for mais interno com
todas as suas interaes. No exemplo acima, o println portanto executado 5*3 = 15 vezes.
Agora um exemplo mais complexo: um programa usado para calcular a mdia de vrias turmas na prova
P1 de uma disciplina:
c l a s s MediasNaP1
{
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g )
{
i n t numeroDeAlunos , numeroDeTurmas , turma , a l u n o ;
d o u b l e n o t a , soma ;
System . o u t . p r i n t ( " Voc q u e r c a l c u l a r a s m d i a s de q u a n t a s t u r m a s ? " ) ;
numeroDeTurmas = S a v i t c h I n . r e a d L i n e I n t ( ) ;
f o r ( t u r m a = 1 ; t u r m a <= numeroDeTurmas ; t u r m a ++)
{
soma = 0 ;
nota = 0;

81

82

CAPTULO 15. LAOS ENCAIXADOS E MATRIZES


System . o u t . p r i n t l n ( " D i g i t e a s n o t a s na P1 da t u r m a " + t u r m a ) ;
System . o u t . p r i n t l n ( " F i n a l i z e a s e q n c i a de n o t a s d i g i t a n d o 1. " ) ;
f o r ( numeroDeAlunos = 0 ; n o t a >= 0 ; numeroDeAlunos ++)
{
nota = SavitchIn . readLineDouble ( ) ;
i f ( n o t a >=0)
soma += n o t a ;
}
System . o u t . p r i n t l n ( "A mdia da t u r m a " + soma /
( numeroDeAlunos 1 ) ) ;
}
}

15.2

Matrizes (arrays multi-dimensionais)

Uma matriz de 1 dimenso, tambm chamada de vetor, implementada em Java usando um array unidimensional como vimos numa aula passada. Matrizes de 2 ou mais dimenses tambm podem ser representadas em
Java atravs de arrays multi-dimensionais. Veja um exemplo:
/ / d e f i n e uma m a t r i z b i d i m e n s i o n a l
int [ ] [ ] matriz ;
/ / a l o c a e s p a o p a r a uma m a t r i z de 5 l i n h a s e 7 c o l u n a s
m a t r i z = new i n t [ 5 ] [ 7 ] ;
matriz [0][0] = 3;
matriz [1][1] = matriz [3][4] + matriz [ 1 ] [ 2 ] ;

muito comum utilizarmos repeties encaixadas quando precisamos percorrer os elementos de matrizes
de duas dimenses ou mais:
int i , j ;
i n t [ ] [ ] t a b u a d a = new i n t [ 1 1 ] [ 1 1 ] ;
f o r ( i = 0 ; i <= 1 0 ; i ++)
f o r ( j = 0 ; j <= 1 0 ; j ++)
tabuada [ i ] [ j ] = i j ;

este trecho de cdigo cria uma matriz de duas dimenses contendo a tabuada de 0 a 10. Note que a primeira
linha e a primeira coluna no precisariam ser inicializados com uma multiplicao, ns poderamos atribuir o
valor 0 diretamente a elas.
Nota interessante: para Java, na verdade uma matriz bidimensional um array de arrays. Ou seja, tabuada
um array onde cada posio do tipo array de inteiros. Dito isto, pense como podemos fazer para descobrir
quantas linhas e quantas colunas possui uma matriz bidimensional. A resposta a seguinte:
void imprimeDimensoes ( i n t [ ] [ ] m a t r i z )
{
System . o u t . p r i n t l n ( "A m a t r i z p o s s u i " +
matriz . length
+ " linhas e " +
matriz [ 0 ] . length
+ " colunas . " ) ;
}

15.3. EXEMPLO: LIFE, O JOGO DA VIDA

83

15.3 Exemplo: LIFE, o jogo da vida


O LIFE um jogo simples de simulao de processos biolgicos criado pelo matemtico John Conway. O
"ambiente"onde se passa a simulao um quadriculado onde so colocadas "clulas", ou seja, preenchidos de
forma inicial. So 3 as regras:
Uma clula viva com menos de 2 vizinhos morre.
Uma clula viva com mais de 3 vizinhos morre.
Uma clula viva aparece quando tem 3 vizinhos vivos exatamente.
O processo de simulao iterativo, ou seja, as regras so aplicadas ao estado inicial que produz um
segundo estado. A este segundo estado so aplicadas as regras novamente e assim sucessivamente, criando
novas "geraes"de clulas ao longo do tempo. Veja um exemplo abaixo:
class Life
{
i n t MAX = 1 0 ;
/ / Tamanho da m a t r i z
i n t [ ] [ ] m a t r i z = new i n t [MAX] [MAX] ;
void i n i c i a l i z a ( )
{
int i , j ;
f o r ( i = 1 ; i < MAX 1 ; i ++)
f o r ( j = 1 ; j < MAX 1 ; j ++)
m a t r i z [ i ] [ j ] = ( i n t ) ( Math . random ( ) 1 . 5 ) ;
/ / o Math . random g e r a um nmero em [ 0 , 1 ] , m u l t i p l i c a n d o
/ / p o r 2 / 3 c o n s e g u i r e m o s 2 / 3 d a s c a s a s com z e r o s e 1 / 3 com 1 s
/ / o ( i n t ) t r a n s f o r m a o d o u b l e o b t i d o em i n t e i r o
/ / o s m a i s o b s e r v a d o r e s podem p e r c e b e r que a s b o r d a s da m a t r i z no
/ / f o r a m i n i c i a l i z a d a s , o j a v a f a z i s t o a u t o m a t i c a m e n t e quando da
/ / a l o c a o da m a t r i z ( new i n t ) .
}
void imprimeTabuleiro ( )
{
int i , j ;
f o r ( i = 0 ; i < MAX; i ++)
{
f o r ( j = 0 ; j < MAX; j ++)
i f ( m a t r i z [ i ] [ j ] == 1 )
System . o u t . p r i n t ( " " ) ;
else
System . o u t . p r i n t ( " . " ) ;
System . o u t . p r i n t l n ( ) ;
}
System . o u t . p r i n t l n ( ) ;
}

84

CAPTULO 15. LAOS ENCAIXADOS E MATRIZES

int vizinhos ( int i , int j )


{
r e t u r n m a t r i z [ i 1][ j 1] + m a t r i z [ i 1][ j ] + m a t r i z [ i 1][ j + 1 ] +
m a t r i z [ i ] [ j 1] + m a t r i z [ i ] [ j + 1 ] +
m a t r i z [ i + 1 ] [ j 1] + m a t r i z [ i + 1 ] [ j ] + m a t r i z [ i + 1 ] [ j + 1 ] ;
}
int [ ] [ ] iteracao ()
{
i n t [ ] [ ] aux = new i n t [MAX] [MAX] ;
int i , j ;
f o r ( i = 1 ; i < MAX 1 ; i ++)
f o r ( j = 1 ; j < MAX 1 ; j ++)
{
i f ( m a t r i z [ i ] [ j ] == 1 )
/ / se est viva
{
i f ( ( vizinhos ( i , j ) < 2) | | ( vizinhos ( i , j ) > 3) )
aux [ i ] [ j ] = 0 ;
/ / morre
else
aux [ i ] [ j ] = 1 ;
/ / continua viva
}
else
/ / s e no e s t v i v a
{
i f ( v i z i n h o s ( i , j ) == 3 )
aux [ i ] [ j ] = 1 ;
/ / aparece vida
else
aux [ i ] [ j ] = 0 ;
/ / c o n t i n u a como e s t a v a
}
}
r e t u r n aux ; / / d e v o l v e a m a t r i z com a v o v a i t e r a o
}
void simulaVida ( i n t quant )
{
int i ;
/ / f a r e m o s a s i m u l a o de q u a n t o s c i c l o s
f o r ( i = 0 ; i < q u a n t ; i ++)
{
imprimeTabuleiro ( ) ;
m a t r i z = i t e r a c a o ( ) ; / / a m a t r i s da i t e r a o a n t e r i o r r e c o l h i d a
/ / p e l o c o l e t o r de l i x o .
}
}
}

..........
...*.****.
....*...*.
....**....

..........
....*****.
...*....*.
......**..

..........
....*****.
....*...*.
....***.*.

..........
....*****.
...*....*.
.......*..

..........
....*****.
....**..*.
...**.....

85

15.4. EXERCCIOS
.**.***.*.
.*....*...
..*...*...
..*.*.....
.....**.*.
..........

.****.**..
.*.*..*...
.***.*....
...*..**..
.....*....
..........

.*.**.....
......**..
.*.*.*.*..
...*.**...
......*...
..........

...**.....
...*.***..
..*..*.*..
..*..*.*..
.....**...
..........

...***.*..
..**.*.*..
..**.*.**.
....**.*..
.....**...
..........

15.4 Exerccios
1. Escreva um mtodo para preencher uma matriz com nmeros inteiros lidos do teclado. O mtodo recebe
a matriz como parmetro.
2. Escreva uma classe com os seguintes mtodos:
Um mtodo que recebe 3 matrizes do tipo double como parmetro, calcula a soma das duas primeiras e guarda o resultado na terceira.
Um mtodo que recebe 3 matrizes do tipo double como parmetro, calcula o produto das duas
primeiras e guarda o resultado na terceira.
Para os dois mtodos anteriores, escrever uma segunda verso que recebe apenas 2 matrizes como
parmetro e devolve o resultado atravs do comando return.
3. Adicionar classe do exerccio anterior um mtodo que recebe duas matrizes quadradas o tipo double
e devolve um boolean indicando se uma inversa da outra. Lembrando da impreciso das contas com
ponto flutuante considere que um nmero igual a zero se ele pertencer a [108 , 108 ]. De forma
anloga considere que um nmero igual a 1 se ele pertencer a [1 108 , 1 + 108 ].
4. Dizemos que uma matriz Anxn um quadrado latino de ordem n se em cada linha e em cada coluna
aparecem todos os inteiros 1,2,3,...,n (ou seja, cada linha e coluna permutao dos inteiros 1,2,...,n).
Escreva uma classe com os seguintes mtodos:
(a) imprimeMatriz(), que imprime uma matriz;
(b) estaNoArray() que recebe como parmetros um inteiro j e um array V de inteiros e verifica se j
ocorre no array;
(c) temTodos que, usando o mtodo acima, que recebe como parmetros um array V com n inteiros e
verifica se em V ocorrem todos os inteiros de 1 a n e
(d) eLatineUsando() que, utilizando o mtodo acima, verifica se uma dada matriz inteira Anxn um
quadrado latino de ordem n.
Veja um exemplo de uso de um objeto da classe nas seguintes iteraes:
Welcome to DrJava.
> QuadradoLatino a = new QuadradoLatino();
> int [][] matriz1 = {{1}};
> a.imprimeMatriz(matriz1)

86

CAPTULO 15. LAOS ENCAIXADOS E MATRIZES


1
> a.eLatino(matriz1)
true
> int [][] matriz2 = {{1,2,3}, {2,3,1}, {3,1,2}};
> a.imprimeMatriz(matriz2)
1 2 3
2 3 1
3 1 2
> a.eLatino(matriz2)
true
> int [][] matriz3 = {{1,2}, {1,2}};
> a.imprimeMatriz(matriz3)
1 2
1 2
> a.eLatino(matriz3)
false
5. Faa uma classe com dois mtodos estticos:
int pertence(int el, int v[], int tam) que verifica se um inteiro el ocorre em um array
v[] com tam elementos, se ocorre devolve a posio, caso contrrio devolve -1.
void frequencia(int v[]) que imprime a freqncia absoluta dos elementos em v.
Dica: para calcular a freqncia absoluta so necessrios dois vetores, um com os elementos distintos e outro com o nmero de ocorrncias. Percorra o array v, verificando para cada posio, se o
nmero armazenado j apareceu
6. Um jogo de palavras cruzadas pode ser representado por uma matriz Amxn onde cada posio da matriz
corresponde a um quadrado do jogo, sendo que 0 indica um quadrado branco e -1 indica um quadrado
preto. Indicar na matriz as posies que so incio de palavras horizontais e/ou verticais nos quadrados
correspondentes (substituindo os zeros), considerando que uma palavra deve ter pelo menos duas letras.
Para isso, numere consecutivamente tais posies.
Exemplo: Dada a matriz:
0
0
0
-1
0

-1
0
0
0
0

0
0
-1
0
-1

-1
0
-1
0
0

A sada dever ser:


1 -1 2 -1
5
6
0
0
8
0 -1 -1
-1 10 0 11
13 0 -1 14

-1
-1
0
0
0
-1
-1
9
0
0

0
0
0
-1
0
3
7
0
-1
0

-1
0
-1
0
-1
-1
0
-1
12
-1

0
0
0
0
-1
4
0
0
0
-1

15.4. EXERCCIOS

87

7. Escreva uma classe com um mtodo que leia um inteiro n e as posies de n rainhas em um tabuleiro de
xadrez e determina se duas rainhas se atacam.

88

CAPTULO 15. LAOS ENCAIXADOS E MATRIZES

Captulo 16

Busca e ordenao
Quais novidades veremos nesta aula?
Busca em array
Ordenao em arrays

16.1 Busca
Como j vimos, arrays podem guardar muita informao embaixo de uma nica varivel. Uma das operaes
mais comuns que podemos fazer em um array buscar um elemento nele. Isso pode ser til para saber se um
elemento j est l para recuperar outras informaes dos objetos armazenados. Lembrando do nosso EP, pense
na busca de um CD pelo ttulo. Sabendo onde o CD est podemos recuperar outras informaes, como as faixas
que o compe, sua durao, etc.
Mas como podemos buscar algo? Vamos primeiro aprender a forma mais simples de busca: a busca seqencial. Neste caso, "varre-se"o array do incio ao fim at encontrarmos o elemento desejado. Isso pode ser feito
usando um simples lao while. Considere que biblioteca um array de objetos da classe Livro. O array
est cheio de livros vlidos (ou seja tem elementos de 0 a bilbioteca.length - 1. Considere ainda que esses
objetos disponibilizam um mtodo pegaNome que retorna o nome do livro. Veja abaixo um exemplo de cdigo
para buscar um livro de nome "Amor em tempos de clera".
int i = 0;
w h i l e ( ( i < b i b l i o t e c a . l e n g t h ) &&
( b i b l i o t e c a [ i ] . pegaNome ( ) . compareTo ( " Amor em t e m p o s de c l e r a " ) ! = 0 ) )
i = i + 1;

Ao final, tempos duas possibilidades:


i < bibliotecas.length: Neste caso o livro est na posio i do array. De posse desse ndice podemos manipular o livro encontrado como quisermos
i == bibliotecas.length: J aqui, o livro no foi encontrado pois passamos do final do vetor
89

90

CAPTULO 16. BUSCA E ORDENAO

Por fim, devemos destacar que h uma certa sutileza no cdigo acima. Note que no segundo caso no
poderamos acessar no vetor na posio i. Isso no ocorre devido a ordem das condies do while. Como a
primeira condio falsa, o computador no precisa testar a segunda para saber que a expresso falsa, j que
a condio um "e-lgico".

16.2 Pondo ordem na casa


Uma das tarefas mais comuns em programas ordenar coisas. Muitas vezes mais fcil trabalhar com os
elementos de um vetor ordenados. Um bom exemplo a busca. Caso o vetor esteja ordenado pela "chave"de
busca possvel fazer algo bem mais eficiente do que a busca seqncial descrita acima.
Mas como podemos ordenar os elementos de um vetor?
Para fazer isso vamos nos lembrar de algo que universitrios fazem muito: jogar baralho. Quando temos
vrias cartas na mo, muitas vezes acabamos por orden-las. Pensem e discutam um pouco como vocs fazem
isso. Existe alguma lgica por trs da maneira que voc move as cartas para l e para c? Ser que voc poderia
descrever um algoritmo para ordenar as cartas?
Agora vamos fazer a brincadeira ficar um pouco mais complicada. Agora, seja qual for o algoritmo que
voc descreveu acima, tente pensar como adapt-lo para incoporar duas restries. Primeiro considere que voc
no pode olhar todas as cartas de uma vez, no mximo duas cartas podem ficar visveis ao mesmo tempo.
Vale, porm, anotar a posio onde uma carta do seu interesse est. Segundo considere que voc no pode
simplesmente mover as cartas de um lugar para outro, mas somente pode trocar duas cartas de posio.
Aposto que a soluo imaginada poderia ser descrita em Java por um dos algoritmos abaixo. Neles desejase ordenar os elementos de 0 at final no vetor de inteiros numeros. Cada algoritmo escrito como um
mtodo.
1. Seleo direta
Neste a cada passo buscamos o menor elemento no vetor e o levamos para o incio. No passo seguinte
buscamos o segundo menor elemento e assim por diante.
v o i d s e l e c a o D i r e t a ( i n t [ ] numeros , i n t f i m )
{
i n t i , j , minimo , temp ;
for ( i = 0 ; i < fim 1 ; i = i + 1)
{
/ / I n i c i a l m e n t e o menor e l e m e n t o j v i s t o o p r i m e i r o e l e m e n t o .
minimo = i ;
for ( j = i + 1 ; j < fim ; j = j + 1)
{
i f ( numeros [ j ] < numeros [ minimo ] )
minimo = j ;
}
/ / C o l o c a o menor e l e m e n t o no i n i c i o do subv e t o r a t u a l .
temp = numeros [ i ] ;
numeros [ i ] = numeros [ minimo ] ;
numeros [ minimo ] = temp ;
}
}

16.2. PONDO ORDEM NA CASA

91

2. Insero direta
A cada passo aumenta a poro ordenada do vetor de uma posio, inserindo um novo elemento na
posio correta.
v o i d i n s e r c a o D i r e t a ( i n t [ ] numeros , i n t f i m )
{
int i , j , atual ;
/ / Cada p a s s o c o n s i d e r a que o v e t o r e s q u e r d a de i e s t o r d e n a d o .
for ( i = 1 ; i < fim ; i = i + 1)
{
/ / T e n t a i n s e r i r m a i s um numero na p o r o i n c i a l do v e t o r que
/ / j e s t o r d e n a d a empurrando p a r a d i r e i t a t o d o s o s e l e m e n t o s
/ / m a i o r e s do que a t u a l .
a t u a l = numeros [ i ] ;
j = i;
w h i l e ( ( j > 0 ) && ( numeros [ j 1] > a t u a l ) )
{
numeros [ j ] = numeros [ j 1 ] ;
j = j 1;
}
numeros [ j ] = a t u a l ;
}
}

3. Mtodo da bolha
Esse mtodo testa se a seqncia est ordenada e troca o par de elementos que gerou o problema.
v o i d b o l h a ( i n t [ ] numeros , i n t f i m )
{
i n t i , j , temp ;
for ( i = fim 1 ; i > 0 ; i = i 1)
{
/ / V a r r e o v e t o r d e s d o i n c i o p r o c u r a n d o e r r o s de ordem .
/ / Como a cada passagem o m a i o r e l e m e n t o s o b e a t s u a
/ / p o s i o c o r r e t a , no h n e c e s s i d a d e de i r a t o f i n a l .
f o r ( j = 1 ; j <= i ; j = j + 1 )
{
/ / Se a ordem e s t e r r a d a p a r a o p a r j 1 e j :
i f ( numeros [ j 1] > numeros [ j ] )
{
/ / T r o c a o s d o i s de l u g a r
temp = numeros [ j 1 ] ;
numeros [ j 1] = numeros [ j ] ;
numeros [ j ] = temp ;
}
}
}
}

Obs: Sempre que pedimos para o System.out.print ou System.out.println imprimirem um array ou


outro objeto qualquer de uma classe definidas por ns ele imprime apenas um nmero estranho (que representa o lugar onde o objeto est armazenado na memria). Deste modo interessante escrever um mtodo

92

CAPTULO 16. BUSCA E ORDENAO

imprimeVetor para que o computador mostre todos os elementos vlidos de seu vetor. Esse mtodo fcil,
basta varrer o vetor e pedir a cada passo que o computador imprima o elemento atual (ou a parte dele que nos
interessa ver).

16.3 Exerccios
1. Neste exerccio veremos como os algoritmos acima descritos se comportam medida que aumentamos
o tamanho do vetor a ser ordena. Escolha um dos algoritmos acima e execute-o utilizando como entrada
vetores de diferenets tamanho. O tempo gasto para realizar a ordenao linear com o tamanho do vetor?

Captulo 17

Busca binria, fuso e o que so as variveis


Quais novidades veremos nesta aula?
Busca binria
Fuso de duas seqncias ordenadas
Diferenas entre variveis que representam tipos primitivos
e aquelas que representam tipos complexos.

17.1 Busca binria


Nesta aula vamos ver alguns dos usos da ordenao. Um exemplo especialmente interessante a busca binria.
Suponha que estamos escrevendo um programa que vai guardar um grande nmero de informaes. Estes
dados mudam pouco no tempo mas so sempre consultados. Um exemplo tpico a lista telefnica, que tem
atualizao anual, mas que consultada vrias vezes por dia no stio da operadora. Neste caso vale pena
"pagar o preo"de guardar os dados ordenados pela chave de busca (no caso da lista, o nome do assinante). Isso
torna a busca, operao freqente, muito mais rpida. A idia bem simples. Como a seqncia esta ordenada,
sabemos que o tem do meio deixa metade dela de cada lado. Se em uma primeira passagem ns simplesmente
perguntarmos qual a posio do valor buscado com relao a esse elemento intermedirio podemos jogar metade
do trabalho fora. H trs possibilidades:
1. O objeto buscado tem a mesma chave do objeto do meio: Ento j encontramos o que queramos e nosso
trabalho acabou.
2. O objeto buscado vem antes do objeto do meio: podemos ento concentrar a busca na poro inicial da
seqncia e esquecer a parte do fim.
3. O objeto buscado fica depois do objeto intermedirio: a busca deve continuar apenas na parte final.
93

94

CAPTULO 17. BUSCA BINRIA, FUSO E O QUE SO AS VARIVEIS

Ou seja podemos, usando o elemento intermedirio, eliminar metade do trabalho a cada passo. Isso faz
com que a busca fique muito mais rpida! Vejamos com fica a implementao da busca binria para um array
de inteiros. Este cdigo pode ser facilmente adaptado para double e cadeias de caracteres.
i n t b u s c a B i n a r i a ( i n t chave , i n t [ ] numeros , i n t f i m )
{
int
esq = 0 ,
d i r = fim 1 ,
meio ;
w h i l e ( e s q <= d i r )
{
meio = ( e s q + d i r ) / 2 ;
i f ( c h a v e > numeros [ meio ] )
e s q = meio + 1 ;
e l s e i f ( c h a v e < numeros [ meio ] )
d i r = meio 1 ;
else
r e t u r n meio ;
}
r e t u r n 1;
}

17.2

Fuso

Um outro algoritmo interessante ligado a seqncias ordenadas a fuso de duas delas. Ou seja, a unio de
duas seqncias ordenadas em uma seqncia maior ainda em ordem. Esta operao conhecida como fuso.
Vejamos como podemos faz-la:
/ / Une d o i s v e t o r e s o r d e n a d o s em um novo v e t o r a i n d a em ordem .
/ / N o t e que e s t e mtodo r e t o r n a um v e t o r .
int [] fusao ( int [] a , int b [ ] )
{
int
posa = 0 ,
posb = 0 ,
posc = 0;
i n t [ ] c = new i n t [ a . l e n g t h + b . l e n g t h ] ;
/ / E n q u a n t o nenhuma d a s d u a s s e q n c i a s e s t v a z i a . . .
w h i l e ( p o s a < a . l e n g t h && p o s b < b . l e n g t h )
{
/ / Pega o menor e l e m e n t o a t u a l e n t r e a e b .
i f ( b [ p o s b ] <= a [ p o s a ] )
{
c [ posc ] = b [ posb ] ;
p o s b ++;
}
else
{
c [ posc ] = a [ posa ] ;

17.3. O QUE GUARDAM AS VARIVEIS?

95

p o s a ++;
}
p o s c ++;
}
/ / Completa
while ( posa
{
c [ posc ] =
p o s c ++;
p o s a ++;
}
while ( posb
{
c [ posc ] =
p o s b ++;
p o s c ++;
}

com a s e q n c i a que a i n d a no acabou .


< a . length )
a [ posa ] ;

< b . length )
b [ posb ] ;

return c ;
}

17.3

O que guardam as variveis?

Em primeiro lugar, vamos usar o nome varivel para designar qualquer nome associado a dados em um programa. Isso inclui os atributos de objetos, parmetros de mtodos e variveis locais. Em Java, uma varivel
associada a um tipo primitivo (int, double, boolean e char tem um comportamento levemente diferente a
variveis associadas a objetos complexos (String, arrays, objetos pertencentes a classes definidas pelo programador, etc.) Vamos tentar explicar as diferenas usando a forma como o Java armazena os dados. Os dados de
tipo primitivo so todos muito simples, ocupando pouco espao de memria. Neste caso vale pena guardar
nessas variveis o seu valor. Logo, sea eb so variveis de mesmo tipo primitivo, a operaoa = b copia ema
o valor que j est emb. Isso explica porque a mudana em um parmetro de tipo primitivo dentro de mtodos
no se reflete fora. O parmetro alterado no tem nenhuma ligao com a varivel que estava em seu lugar
na chamada alm da copia inicial de valor. J para objetos complexos, como cadeias de caracteres, arrays e
qualquer objeto de uma classe definida pelo programador a situao bem diferente. Estes objetos podem ser
muito complicados, ocupando muito espao de memria. Neste caso o Java no guarda nas variveis uma cpia do objeto, mas simplesmente guarda a posio na memria que este objeto ocupa. Por este motivo, fala-se
que em Java as variveis associadas a objetos complexos so referncias para este objetos. No momento que
o objeto precisa ser usado, Java recupera-o a partir de sua localizao. Esta pequena diferena gera algumas
surpresas. Considere que temos uma classe chamadaFruta com um atributopreco e mtodoscarregaPreco
eimprimePreco. O que ocorre quando rodamos o seguinte cdigo?
F r u t a a = new F r u t a ( ) ;
a . carregaPreco (10);
Fruta b = a ;
b . carregaPreco (100);
a . imprimePreco ( ) ;

Observamos que o preo da frutaa mudou. Isto ocorreu porquea eb so referncias para um mesmo objeto
na memria. Como dois apelidos para mesma pessoa. Qualquer coisa que ocorre com um objeto usando um

96

CAPTULO 17. BUSCA BINRIA, FUSO E O QUE SO AS VARIVEIS

de seus apelidos se reflete para a viso do outro apelido. Esse raciocnio explica porque alteraes em objetos
complexos dentro de um mtodo se propagam para fora. O parmetro associado a esse objeto tambm um
apelido.

Captulo 18

Construtores e especificadores de acesso


Quais novidades veremos nesta aula?
Construtores
Especificadores de acesso
final e static

18.1 Construtores
Desde o incio do curso at agora ns trabalhamos com diversos objetos diferentes. Mas, antes de comear a
usar um objeto de uma classe X, ns devemos cri-lo. Isto foi feito at agora atravs de chamadas do tipo: X x
= new X(); na qual a varivel x passa a se referir a um novo objeto da classe X.
Na linguagem Java, quando no especificamos como um objeto deve ser criado, a prpria linguagem nos
fornece um construtor padro. Vejamos com mais detalhes um exemplo abaixo:
c l a s s Ex1
{
int a ;
double d ;
String s ;
boolean b ;
void imprime ( )
{
System . o u t . p r i n t l n ( " o i n t e i r o v a l e " + a ) ;
System . o u t . p r i n t l n ( " o r e a l v a l e " + d ) ;
System . o u t . p r i n t l n ( " a S t r i n g v a l e " + s ) ;
System . o u t . p r i n t l n ( " o b o o l e a n v a l e " + b ) ;
}
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s )
{
Ex1 e = new Ex1 ( ) ;

97

98

CAPTULO 18. CONSTRUTORES E ESPECIFICADORES DE ACESSO


e . imprime ( ) ;
}

No exemplo acima podemos ver que os nmeros foram inicializados automaticamente com zero, a String
com null e o boolean com false. A inicializao com a referncia nula, null o padro para as referncias
a objetos em geral.
Mas, e se por alguma razo queremos que as variveis da classe tenham algum valor pr-definido, ou
melhor ainda, que seja definido durante a "construo"do objeto. Neste caso podemos definir explicitamente
um construtor. Veja o exemplo abaixo:
c l a s s Ex2
{
int a ;
double d ;
String s ;
boolean b ;
Ex2
{
a =
d =
s =
b =
}

( i n t i 1 , d o u b l e d1 , S t r i n g s1 , b o o l e a n b1 )
i1 ;
d1 ;
s1 ;
b1 ;

void imprime ( )
{
System . o u t . p r i n t l n ( " o i n t e i r o v a l e " + a ) ;
System . o u t . p r i n t l n ( " o r e a l v a l e " + d ) ;
System . o u t . p r i n t l n ( " a S t r i n g v a l e " + s ) ;
System . o u t . p r i n t l n ( " o b o o l e a n v a l e " + b ) ;
}
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s )
{
/ / Ex2 e = new Ex2 ( ) ;
ERRO no podemos m a i s u s a r o c o n s t r u t o r p a d r o
Ex2 o b j 1 = new Ex2 ( 2 , 3 . 1 4 , " Oi " , t r u e ) ;
Ex2 o b j 2 = new Ex2 ( 1 , 1 . 0 , " Tudo 1 " , t r u e ) ;

obj1 . imprime ( ) ;
System . o u t . p r i n t l n ( ) ;
obj2 . imprime ( ) ;
}
}

A primeira observao importante que no podemos mais usar o construtor padro. Se a prpria classe
nos fornece um construtor, de se esperar que devamos respeitar algumas regras na hora de construir o objeto,
logo o construtor padro no est mais disponvel.
Podemos tambm pensar em um exemplo um pouco mais sofisticado, criando uma classe que representa
contas em um banco. Como atributos bvios podemos pensar em ter o nome do titular e o saldo de cada conta.
natural, que no possamos criar contas sem titular, logo no construtor sempre ser necessrio fornecer um
nome (String).

18.1. CONSTRUTORES

99

c l a s s Conta
{
String t i t u l a r ;
double s a l d o ;
Conta ( S t r i n g s , double v a l )
{
titular = s;
saldo = val ;
}
void imprime ( )
{
System . o u t . p r i n t l n ( "O c l i e n t e : " + t i t u l a r + " tem s a l d o " + s a l d o ) ;
}
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s )
{
C o n t a c1 = new C o n t a ( " J o s " , 1 0 0 ) ;
C o n t a c2 = new C o n t a ( " M a r i a " , 1 0 0 0 ) ;

c1 . i m p r i m e ( ) ;
System . o u t . p r i n t l n ( ) ;
c2 . i m p r i m e ( ) ;
}
}

Mesmo no exemplo bem simples acima podemos notar que uma operao usual a criao de contas com
saldo zero. Logo, parece natural que tenhamos um construtor que receba apenas o nome, e no o saldo (ficando
subentendido neste caso que no houve depsito inicial).
Conta ( S t r i n g s )
{
titular = s;
saldo = 0;
}

Pode-se observar tambm que podemos reescrever o construtor acima usando funcionalidades do primeiro
construtor.
Conta ( S t r i n g s )
{
this ( s , 0.0);
}

Para isso usamos uma palavra reservada da linguagem Java, a palavra this que nada mais do que uma
referncia ao prprio objeto. Isto , quando o construtor Conta("Joo") chamado, ele repassa o trabalho ao
outro construtor usando saldo 0.
Tambm interessante notar a diferena entre os dois construtores, como eles tem o mesmo nome (nome
da classe), a nica diferena entre eles est nos parmetros recebidos. O compilador Java escolhe o construtor
correto conforme a assinatura (parmetros e sua ordem). Esta mesma tcnica tambm pode ser usada se precisarmos de dois mtodos com o mesmo nome, mas que recebam parmetros diferentes. Isto chamado de
polimorfismo de nome.

100

CAPTULO 18. CONSTRUTORES E ESPECIFICADORES DE ACESSO

Tambm interessante ressaltar um outro uso da palavra chave this. Vamos supor que adicionamos um
novo parmetro para as contas, o RG. Logo, teremos um atributo a mais: String RG. Se por acaso quisermos
criar um novo construtor que receba um parmetro tambm chamado de RG, isto se torna possvel.
C o n t a ( S t r i n g s , d o u b l e v a l , S t r i n g RG)
{
titular = s;
saldo = val ;
t h i s . RG = RG;
}

No caso, o this refora que estamos falando de um dos atributos do objeto. At hoje no havamos usado
o this pois tomamos cuidado para escolher os nomes de parmetros e variveis locais diferentes dos nomes
dos atributos.

18.2

Especificadores de acesso

Continuando com o exemplo anterior, poderamos adicionar mtodos seguros para efetuar depsitos e saques.
void saque ( double v a l )
{
i f ( v a l <= s a l d o ) {
System . o u t . p r i n t l n ( " Saque e f e t u a d o com s u c e s s o " ) ;
saldo = saldo val ;
} else
System . o u t . p r i n t l n ( " S a l d o INSUFICIENTE " ) ;
imprime ( ) ;
}
void d e p o s i t o ( double v a l )
{
saldo = saldo + val ;
imprime ( ) ;
}

No cdigo acima, no caso de saque veramos mensagens avisando sobre o sucesso ou falha na operao.
Existem outras formas mais bonitas de mostrar as falhas atravs de Excees (Exceptions), mas estas fogem
ao escopo deste curso. Entretanto, um usurio poderia autorizar saques quaisquer, da seguinte forma:
C o n t a c2 = new C o n t a ( " M a r i a " , 1 0 0 0 ) ;
c2 . i m p r i m e ( ) ;
c2 . s a l d o = c2 . s a l d o 1 0 0 0 0 0 ;
c2 . i m p r i m e ( ) ;

Pois, neste caso o usurio do objeto do tipo Conta estaria interagindo diretamente com atributos do objeto,
mexendo nas suas partes internas. Para evitar isto podemos usar protees explcitas, indicando que s mtodos
do prprio objeto possam alterar os seus atributos. Isto feito com a palavra chave private. Se os atributos
do Conta forem declarados da seguinte forma:
c l a s s Conta
{
private String t i t u l a r ;

18.3. EXERCCIOS

101

p r i v a t e double s a l d o ;
p r i v a t e S t r i n g RG;
...
}

No haver mais acesso direto aos atributos de objetos da classe Conta. O oposto de private public que
d acesso irrestrito. Os especificadores de acesso tambm podem ser usados com os mtodos. Quando nenhum
especificador utilizado, a linguagem Java usa o acesso amigvel (friendly) que s permite a visibilidade dentro
do mesmo pacote.
Um outro qualificador interessante o static que indica quais atributos devem ser considerados como da
classe e no especficos a cada objeto. Veja o seguinte exemplo:
class TesteStatic {
s t a t i c int quantidade = 0;
TesteStatic ()
{
System . o u t . p r i n t l n ( " C r i a n d o um o b j e t o do t i p o T e s t e S t a t i c " ) ;
q u a n t i d a d e ++;
System . o u t . p r i n t l n ( " At a g o r a f o r a m c r i a d o s : " + q u a n t i d a d e + "
objetos TesteStatic " );
}
}

A cada objeto TesteStatic criado veremos quantos objetos deste tipo j foram criados anteriormente.
Observem que no uma prtica usual colocar impresses no construtor, mas de forma a apresentar um exemplo
simples optamos por tomar esta liberdade. Alm disto, mtodos static tambm so mtodos de classe, isto ,
podem ser chamados, mesmo que no existam objetos da classe criados. Um exemplo j visto so as funes da
classe Math como por exemplo Math.sin(double x). O mtodo main tambm esttico pois ao iniciarmos
a execuo de um programa no existe objeto criado.
Finalmente, um ltimo qualificador interessante o final que serve para definir variveis que no podem
mais ter o seu valor modificado, como por exemplo final double PI = 3.1415926538;

18.3 Exerccios
1. (difcil): Como fazer para criar uma classe na qual s seja possvel construir um nico objeto.
Dica: Limitar o acesso ao construtor.

102

CAPTULO 18. CONSTRUTORES E ESPECIFICADORES DE ACESSO

Captulo 19

Interfaces
Quais novidades veremos nesta aula?
Interfaces

19.1 O Conceito de Interfaces


Um dos conceitos principais de orientao a objetos o encapsulamento, atravs do qual, tanto os atributos,
como a prpria implementao das classes no visvel ao usurio da classe. Logo, conhecendo-se a interface
de uma classe, isto , os mtodos disponveis e suas respectivas assinaturas, podemos utilizar objetos desta
classe sem conhecer detalhes de como ela implementada internamente.
Alm disto, existem casos, onde existe a necessidade de se ter uma classe mas no queremos implement-la.
Neste caso, pode-se terceirizar a implementao, fornecendo como especificao a interface desejada.

19.2 Um primeiro exemplo


Vejamos um exemplo prtico: voc tem a misso de criar um zoolgico virtual com vrios tipos de animais.
Voc gostaria de enviar as seguintes mensagens a cada animal:
nasa();
passeiePelaTela();
durma();
Mas, apesar de voc ser especialista em computao voc conhece muito pouco a respeito de animais, logo
voc ter que pedir a outros programadores que conhecem bem os animais as seguintes classes: Ornitorrinco,
Morcego e Zebra. Logo, voc passar a seguinte especificao:
103

104

CAPTULO 19. INTERFACES

i n t e r f a c e Animal
{
void nasa ( ) ;
void p a s s e i e P e l a T e l a ( ) ;
v o i d durma ( ) ;
}

O programador que for implementar o morcego ter que dizer explicitamente que vai usar a interface
Animal, isto feito atravs da palavra chave implements. Como o objetivo de apresentar como funcionam as interfaces, o cdigo dos animais ser apenas composto de comandos de impresso de mensagens.
p u b l i c c l a s s Morcego implements Animal
{
public void nasa ( )
{
System . o u t . p r i n t l n ( " Nasce um l i n d o morcego " ) ;
}
public void p a s s e i e P e l a T e l a ( )
{
System . o u t . p r i n t l n ( " Voa de um l a d o p a r a o o u t r o " ) ;
}
p u b l i c v o i d durma ( )
{
System . o u t . p r i n t l n ( " Dorme de p o n t a c a b e a " ) ;
}
}

A palavra chave implements obriga o programador a escrever o cdigo correspondente a todos os mtodos com suas respectivas assinaturas. Alm disto, todos os mtodos da interface devem ser obrigatoriamente
pblicos. Vejamos as implementaes das outras classes:
p u b l i c c l a s s O r n i t o r r i n c o implements Animal
{
public void nasa ( )
{
System . o u t . p r i n t l n ( " Quebra o ovo p a r a s a i r " ) ;
}
public void p a s s e i e P e l a T e l a ( )
{
System . o u t . p r i n t l n ( " Anda e n a d a de um l a d o p a r a o o u t r o " ) ;
}
p u b l i c v o i d durma ( )
{
System . o u t . p r i n t l n ( " D e n t r o de t n e i s , d u r a n t e o d i a " ) ;
}
}
p u b l i c c l a s s Z e b r a implements Animal
{
int l ;
/ / nmero de l i s t r a s da z e b r a
public Zebra ( i n t i )
{
l = i ; / / c r i a uma z e b r a com i l i s t r a s
}

19.2. UM PRIMEIRO EXEMPLO

105

public void nasa ( )


{
System . o u t . p r i n t l n ( " Nasce m a i s uma z e b r a " ) ;
}
public void p a s s e i e P e l a T e l a ( )
{
System . o u t . p r i n t l n ( " G a l o p a p e l o campo " ) ;
}
p u b l i c v o i d durma ( )
{
System . o u t . p r i n t l n ( " Dorme de p " ) ;
}
/ / nada i m p e d e que s e j a m i m p l e m e n t a d o s m t o d o s a d i c i o n a i s
public void c o n t a L i s t r a s ( )
{
System . o u t . p r i n t l n ( " E s t a z e b r a tem " + l + " l i s t r a s
" );
}
}

(Em tempo). Existe uma regra em Java com relao ao nmero de classes pblicas que podem existir em
um arquivo .java. Em cada arquivo deve existir no mximo uma classe pblica, sendo que caso exista uma, o
nome do arquivo deve ser igual ao nome da classe pblica. Logo, no exemplo acima, as classes Ornitorrinco,
Morcego e Zebra devem estar em arquivos separados, com respectivos nomes: Ornitorrinco.java, Morcego.java
e Zebra.java.
Mas, o uso da interface um pouco mais amplo, podemos considerar que cada um dos animais alm de
ser um objeto da prpria classe tambm um objeto do tipo Animal. interessante ressaltar que no podemos
criar novos objetos a partir da interface Animal. Vejamos mais um exemplo:
class ZoologicoVirtual
{
s t a t i c p u b l i c v o i d c i c l o D e V i d a ( Animal a n i m a l )
{
animal . nasa ( ) ;
animal . p a s s e i e P e l a T e l a ( ) ;
a n i m a l . durma ( ) ;
}
s t a t i c public void f a z F u n c i o n a r ( )
{
Zebra
z1 = new Z e b r a ( 1 0 2 ) ;
/ / c r i a duas z e b r a s
Animal
z2 = new Z e b r a ( 1 0 1 ) ;
/ / s e n d o uma do t i p o A n i m a l
Morcego
m1 = new Morcego ( ) ;
O r n i t o r r i n c o o1 = new O r n i t o r r i n c o ( ) ;
c i c l o D e V i d a ( z1 ) ;
c i c l o D e V i d a ( z2 ) ;
c i c l o D e V i d a ( m1 ) ;
c i c l o D e V i d a ( o1 ) ;
}
}

Veja o exemplo do painel de iteraes abaixo:


> ZoologicoVirtual.fazFuncionar()

106

CAPTULO 19. INTERFACES

Nasce mais uma zebra


Galopa pelo campo
Dorme de p
Nasce mais uma zebra
Galopa pelo campo
Dorme de p
Nasce um lindo morcego
Voa de um lado para o outro
Dorme de ponta cabea
Quebra o ovo para sair
Anda e nada de um lado para o outro
Dentro de tneis, durante o dia
>
Observe que apesar de z2 ter sido definido como uma nova Zebra, a referncia para um objeto do tipo
Animal, logo chamadas do tipo z2.contaListras(); no so vlidas, mas chamadas a z1.contaListras() so.

19.3 Implementando mais de uma interface por vez


Vimos acima que podemos ver objetos como sendo do mesmo tipo, desde que eles implementem a mesma
interface. Isto tambm vlido no caso de objetos implementarem vrias interfaces (pensando no mundo real
isto acontece muito mais freqentemente). Vejam as duas interfaces seguintes:
i n t e r f a c e Voador
{
v o i d voa ( ) ;
void a t e r r i s s a ( ) ;
}
interface TransportadorDePessoas
{
void entramPessoas ( ) ;
void saemPessoas ( ) ;
}

Agora vamos pensar em trs classes: Ave, Onibus e Aviao. As classes Ave e Onibus podem implementar
a primeira e segunda interface, respectivamente.
c l a s s Ave implements Voador
{
p u b l i c v o i d voa ( )
{
System . o u t . p r i n t l n ( " B a t e a s a s a s bem f o r t e " ) ;
}
public void a t e r r i s s a ( )
{
System . o u t . p r i n t l n ( " B a t e a s a s a s m a i s f r a c o e pe o s p s no c h o " ) ;
}
}

19.3. IMPLEMENTANDO MAIS DE UMA INTERFACE POR VEZ


c l a s s O n i b u s implements T r a n s p o r t a d o r D e P e s s o a s
{
public void entramPessoas ( )
{
System . o u t . p r i n t l n ( " Abre a s p o r t a s e e n t r a m a s p e s s o a s " ) ;
}
public void saemPessoas ( )
{
System . o u t . p r i n t l n ( " Abre a s p o r t a s e saem a s p e s s o a s " ) ;
}
}

Finalmente, podemos ver o Aviao que implementa as duas interfaces:


c l a s s Aviao implements Voador , T r a n s p o r t a d o r D e P e s s o a s
{
p u b l i c v o i d voa ( )
{
System . o u t . p r i n t l n ( " L i g a a s t u r b i n a s , r e c o l h e o t r e m de p o u s o " ) ;
}
public void a t e r r i s s a ( )
{
System . o u t . p r i n t l n ( " A b a i x a o t r e m de p o u s o e d e s c e " ) ;
}
public void entramPessoas ( )
{
System . o u t . p r i n t l n ( " P r o c e d i m e n t o de embarque " ) ;
}
public void saemPessoas ( )
{
System . o u t . p r i n t l n ( " P r o c e d i m e n t o de d e s e m b a r q u e " ) ;
}
}

Observe o trecho abaixo:


public class TesteDeInterface
{
s t a t i c public void faz ( )
{
O n i b u s o = new O n i b u s ( ) ;
Ave
a = new Ave ( ) ;
Aviao v = new Aviao ( ) ;
o . entramPessoas ( ) ;
o . saemPessoas ( ) ;
a . voa ( ) ;
a. aterrissa ();
/ / com o O n i b u s e Ave nao da p a r a chamar a o u t r a i n t e r f a c e
v . entramPessoas ( ) ;
v . voa ( ) ;
v. aterrissa ();
v . saemPessoas ( ) ;
}
}

107

108

CAPTULO 19. INTERFACES

Uma boa prtica seguida por bons programadores OO "Programe para as interfaces, no para as implementaes". Em outras palavras, toda vez em que voc escrever cdigo que utiliza outras classes, no pense em
como essas outras classes so implementadas internamente, pense apenas na sua interface. Nunca baseie o seu
cdigo em alguma idiossincrazia interna da classe, use apenas conceitos que so claros a partir da interfaces
das classes que voc usa.

19.4

Um exemplo mais sofisticado

Vamos supor que temos uma classe Fruta com os seguintes atributos: peso, valor e nome. Os trs atributos
j devem ser carregados no construtor.
class Fruta
{
double peso ;
double v a l o r ;
S t r i n g nome ;
F r u t a ( S t r i n g n , double v , double p )
{
nome = n ;
valor = v ;
peso = p ;
}
void imprimeFruta ( )
{
System . o u t . p r i n t l n ( nome + " p e s a : " + p e s o
+ "g e valor : " + valor ) ;
}
}

Queremos criar um vetor de Frutas, o qual queremos ordenar primeiro por valor e posteriormente por
peso. Como fazer isto ? Observando os procedimentos de ordenao j vistos fcil ver que a nica mudana
o critrio de comparao.
public class OrdenaFrutas
{
F r u t a f r u t a s [ ] = new F r u t a [ 5 ] ;
public OrdenaFrutas ( )
{
f r u t a s [ 0 ] = new F r u t a ( " L a r a n j a " , 0 . 5 , 1 0 0 ) ;
f r u t a s [ 1 ] = new F r u t a ( " Maa " , 0 . 8 , 1 2 0 ) ;
f r u t a s [ 2 ] = new F r u t a ( "Mamo" , 1 . 2 , 1 1 0 ) ;
f r u t a s [ 3 ] = new F r u t a ( " C e r e j a " , 5 . 0 , 2 0 ) ;
f r u t a s [ 4 ] = new F r u t a ( " J a c a " , 0 . 4 , 5 0 0 ) ;
}
p u b l i c void imprime ( )
{
f o r ( i n t i = 0 ; i < f r u t a s . l e n g t h ; i ++)
f r u t a s [ i ] . imprime ( ) ;

19.4. UM EXEMPLO MAIS SOFISTICADO


}
public void ordenaPreco ( )
{
int i , j ;
Fruta atual ;
/ / Cada p a s s o c o n s i d e r a que o v e t o r e s q u e r d a
/ / de i e s t o r d e n a d o .
f o r ( i = 1 ; i < f r u t a s . l e n g t h ; i ++)
{
atual = frutas [ i ];
j = i;
w h i l e ( ( j > 0 ) && ( f r u t a s [ j 1 ] . v a l o r > a t u a l . v a l o r ) )
{
f r u t a s [ j ] = f r u t a s [ j 1];
j = j 1;
}
frutas [ j ] = atual ;
}
}
public void ordenaPeso ( )
{
int i , j ;
Fruta atual ;
/ / Cada p a s s o c o n s i d e r a que o v e t o r e s q u e r d a
/ / de i e s t o r d e n a d o .
f o r ( i = 1 ; i < f r u t a s . l e n g t h ; i ++)
{
atual = frutas [ i ];
j = i;
w h i l e ( ( j > 0 ) && ( f r u t a s [ j 1 ] . p e s o > a t u a l . p e s o ) )
{
f r u t a s [ j ] = f r u t a s [ j 1];
j = j 1;
}
frutas [ j ] = atual ;
}
}
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s )
{
O r d e n a F r u t a s f e i r a = new O r d e n a F r u t a s ( ) ;
System . o u t . p r i n t l n ( " D e s o r d e n a d o " ) ;
f e i r a . imprime ( ) ;
System . o u t . p r i n t l n ( "Em ordem de v a l o r " ) ;
f e i r a . ordenaPreco ( ) ;
f e i r a . imprime ( ) ;
System . o u t . p r i n t l n ( "Em ordem de p e s o " ) ;
f e i r a . ordenaPeso ( ) ;
f e i r a . imprime ( ) ;
}
}

109

110

CAPTULO 19. INTERFACES

No programa acima, fica claro que tivemos que duplicar o cdigo de ordenao. Mas, e se existissem outros
critrios para ordenao, teramos que fazer isto novamente ? A resposta no, baseado no nosso conhecimento
de interfaces, poderiamos criar uma interface comparadora:
i n t e r f a c e ComparadorDeFrutas
{
i n t compara ( F r u t a a , F r u t a b ) ;
}

Para este mtodo poderamos definir que se a for menor que b, o mtodo devolve -1, se a for igual a b, o
mtodo devolve 0, e finalmente 1 se a for maior que b. Vejamos o caso de peso:
c l a s s ComparaPeso implements C o m p a r a d o r D e F r u t a s
{
p u b l i c i n t compara ( F r u t a a , F r u t a b )
{
i f ( a . peso < b . peso )
r e t u r n 1;
e l s e i f ( a . p e s o == b . p e s o )
return 0;
return 1;
}
}

Da mesma forma podemos escrever uma comparao de valor:


c l a s s ComparaValor implements C o m p a r a d o r D e F r u t a s
{
p u b l i c i n t compara ( F r u t a a , F r u t a b )
{
if ( a . valor < b . valor )
r e t u r n 1;
e l s e i f ( a . v a l o r == b . v a l o r )
return 0;
return 1;
}
}

Agora, basta colocar como parmetro adicional do mtodo de ordenao o comparador desejado:
public class OrdenaFrutas
{
F r u t a f r u t a s [ ] = new F r u t a [ 5 ] ;
public OrdenaFrutas ( )
{
f r u t a s [ 0 ] = new F r u t a ( " L a r a n j a " , 0 . 5 , 1 0 0 ) ;
f r u t a s [ 1 ] = new F r u t a ( " Maa " , 0 . 8 , 1 2 0 ) ;
f r u t a s [ 2 ] = new F r u t a ( "Mamo" , 1 . 2 , 1 1 0 ) ;
f r u t a s [ 3 ] = new F r u t a ( " C e r e j a " , 5 . 0 , 2 0 ) ;
f r u t a s [ 4 ] = new F r u t a ( " J a c a " , 0 . 4 , 5 0 0 ) ;
}
p u b l i c void imprime ( )
{
f o r ( i n t i = 0 ; i < f r u t a s . l e n g t h ; i ++)

111

19.5. EXERCCIOS:
f r u t a s [ i ] . imprime ( ) ;
}
public void ordena ( ComparadorDeFrutas c )
{
int i , j ;
Fruta atual ;
/ / Cada p a s s o c o n s i d e r a que o v e t o r e s q u e r d a
/ / de i e s t o r d e n a d o .
f o r ( i = 1 ; i < f r u t a s . l e n g t h ; i ++)
{
atual = frutas [ i ];
j = i;
w h i l e ( ( j > 0 ) && ( c . compara ( f r u t a s [ j 1] , a t u a l ) == 1 ) )
{
f r u t a s [ j ] = f r u t a s [ j 1];
j = j 1;
}
frutas [ j ] = atual ;
}
}
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s )
{
O r d e n a F r u t a s f e i r a = new O r d e n a F r u t a s ( ) ;
System . o u t . p r i n t l n ( " D e s o r d e n a d o " ) ;
f e i r a . imprime ( ) ;
System . o u t . p r i n t l n ( "Em ordem de v a l o r " ) ;
ComparaValor cmpValor = new ComparaValor ( ) ;
f e i r a . o r d e n a ( cmpValor ) ;
f e i r a . imprime ( ) ;
System . o u t . p r i n t l n ( "Em ordem de p e s o " ) ;
ComparaPeso cmpPeso = new ComparaPeso ( ) ;
f e i r a . o r d e n a ( cmpPeso ) ;
f e i r a . imprime ( ) ;
}
}

A incluso de um novo mtodo para imprimir as frutas em ordem alfabtica agora trivial.

19.5

Exerccios:

1. Escreva classes Quadrado e Crculo com a seguinte interface:


interface
{
double
double
void
String
}

Figura2D
calcularea ( ) ;
calculaPermetro ();
mudaCor ( S t r i n g c o r ) ;
pegaCor ( ) ;

112

CAPTULO 19. INTERFACES

2. Escreva duas implementaes para a interface VeculoDeCorrida, a seguir:


interface VeculoDeCorrida
{
S t r i n g marca ( ) ;
S t r i n g modelo ( ) ;
String cor ( ) ;
in t potnciaEmCavalos ( ) ;
}

Agora, escreva um mtodo veculoPreferido() que recebe um array de veculos de corrida como
parmetro e dentre os veculos vermelhos, imprime a marca e o modelo do que possuir a maior potncia.
3. Voc foi contratado para trabalhar em um berrio (!!!) e no seu primeiro dia de trabalho, deve escreve
uma classe para informar aos pais, dados sobre os seus bebs. A dificuldade que muitos estrangeiros
freqentam esse berrio e o seu programa deve ser capaz de dar informaes em portugus e em ingls
(e, futuramente, em outros idiomas tambm). Para permitir isso, voc dever prover duas implementaes
da interface a seguir que indica mensagens de texto que devero ser mostradas aos pais:
interface
{
String
String
String
String
}

MensagensSobreNeoNatal
nomeDoBeb ( S t r i n g nome ) ;
d a t a D e N a s c i m e n t o ( Beb b ) ;
p e s o ( d o u b l e p e s o Em Q u i l o s ) ;
t e m p e r a t u r a ( double t e m p e r a t u r a E m C e l s i u s ) ;

Ao se chamar o mtodo nomeDoBeb, por exemplo, sua implementao deve devolver uma mensagem
como "O nome do beb Godofredo Manoelino de Moraes". Ao se chamar o mtodo peso, deve-se
devolver algo como "O peso do beb 3140 gramas ". A primeira implementao deve se chamar MensagensBrasileiras e a segunda MensagensEstadosunidenses. As mensagens para os americanos devem
apresentar o peso em libras ("pounds") e a temperatura em graus fahrenheit. A interface Beb (que vocs
no precisam implementar, podem supor que o berario j possui as implementaes), a seguinte:
i n t e r f a c e Beb
{
S t r i n g nome ( ) ;
int diaNascimento
i n t mesNascimento
i n t anoNascimento
double peso ( ) ; / /
double t e m p e r a t u r a
}

();
();
();
SI , ou s e j a , em q u i l o s
( ) ; / / SI , ou s e j a , em c e l s i u s

A classe que o berrio vai usar para imprimir as informaes para os pais ter um mtodo similar ao
seguinte:
class Berario
{
Bebe [ ] L i s t a D e B e b s ;
/ / a q u i vo o u t r o s m t o d o s p a r a i n s e r o e
/ / remoo de b e b s da l i s t a

19.5. EXERCCIOS:

v o i d i m p r i m e D a d o s S o b r e B e b e ( Beb b , M e n s a g e n s S o b r e N e o N a t a l m)
{
System . o u t . p r i n t l n (m. nomeDoBeb ( b . nome ( ) ) ;
System . o u t . p r i n t l n (m. d a t a D e N a s c i m e n t o ( b ) ;
System . o u t . p r i n t l n (m. p e s o ( b . p e s o ( ) ) ;
System . o u t . p r i n t l n (m. t e m p e r a t u r a ( b . t e m p e r a t u r a ( ) ) ;
}
v o i d i m p r i m e ( i n t IDdoBeb , S t r i n g i d i o m a )
{
M e n s a g e n s S o b r e N e o N a t a l m;
i f ( i d i o m a . compareTo ( " P o r t u g u s " ) == 0 )
m = new M e n s a g e n s B r a s i l e i r a s ( ) ;
else
m = new M e n s a g e n s E s t a d o s u n i d e n s e s ( ) ;
i m p r i m e D a d o s S o b r e B e b e ( b e b e s [ IDdoBebe ] , m ) ;
}
}

4. Dada a classe
c l a s s Pessoa
{
S t r i n g nome ;
in t rg ;
int cpf ;
}

escreva duas implementaes da interface


interface LocalizadorDePessoas
{
P e s s o a l o c a l i z a P o r R G ( i n t rg , P e s s o a [ ] vp ) ;
}

utilizando busca sequencial e busca binria.

113

114

CAPTULO 19. INTERFACES

Captulo 20

Herana
Quais novidades veremos nesta aula?
Herana

Esta a verso quase final, ainda vou incluir o exerccio da Conta corrente que dei em aula

20.1

O Conceito de Herana

A demanda pela construo de software em nossa sociedade muito grande. O nmero de bons programadores
disponveis relativamente pequeno. Por isso, os projetistas de linguagens e sistemas de computao tm buscado formas de acelerar e facilitar o desenvolvimento de software. Uma das principais abordagens utilizadas a
re-utilizao de cdigo. Se conseguirmos escrever cdigo que re-utilizado em diversos programas diferentes,
teremos economizado tempo pois no ser necessrio reescrever este cdigo para cada novo programa.
A biblioteca de classes de Java um exemplo de classes que foram escritas pelos programadores da Sun e
que so re-utilizadas diariamente por milhares de programadores ao redor do mundo. Porm, algumas vezes,
o programador necessita fazer alguma modificao em uma classe existente pois ela no atende exatamente
s necessidades de um dado programa. Em alguns casos deseja-se modificar a implementao de um de seus
mtodos, em outros casos deseja-se acrescentar alguma funcionalidade extra classe, acrescentando-se alguns
mtodos e atributos adicionais.
Esta re-utilizao de cdigo com extenses e modificaes, pode ser obtida em linguagens orientadas a
objetos atravs do conceito de Herana. A figura 20.1 mostra um diagrama contendo 4 classes que se relacionam
entre si atravs de herana.
Este diagrama de classes segue um padro chamado UML (Unified Modeling Language). Este padro
muito utilizado para modelar programas orientados a objetos, mas no veremos mais detalhes sobre ele neste
livro. Apresentamos o diagrama aqui apenas a ttulo de ilustrao.
115

116

CAPTULO 20. HERANA

Figura 20.1: Diagrama de herana

20.2 Terminologia de herana


Dizemos que Pessoa a superclasse de Aluno e de Professor.
Professor subclasse de Pessoa e superclasse de ProfessorDoutor.
Dizemos ainda que Aluno herda de Pessoa os seus atributos e mtodos; ou que Aluno estende a class
Pessoa.
Dizemos que Pessoa pai (ou me ) de Professor; e que Professor filho (a) de Pessoa.

20.3 Implementao de herana na linguagem Java


Para especificar, em Java, que uma classe B subclasse de A, utilizamos a palavra extends:
class A
{
i n t a1 ;
v o i d p a t a ( ) { a1 = 1 ; }
}
c l a s s B extends A
{
i n t b1 ;
void vina ( )
{
pata ( ) ;
b1 = a1 ;
}
}

Note que B contm os mtodos e atributos de A e ainda acrescenta um novo atributo e um novo mtodo.
Vejamos agora um exemplo mais complexo que implementa, em Java, o diagrama de classes apresentado
no diagrama UML acima.

20.3. IMPLEMENTAO DE HERANA NA LINGUAGEM JAVA


c l a s s Pessoa
{
p r i v a t e S t r i n g nome ;
p r i v a t e char s e x o ;
p r i v a t e S t r i n g CPF ;
p r i v a t e S t r i n g RG;
p r i v a t e i n t anoDeNascimento ;
v o i d imprimeDados ( )
{
i f ( s e x o == F )
System . o u t . p r i n t l n ( "A S r a . " + nome + " n a s c e u no ano " +
a n o D e N a s c im e n t o +
" . CPF : " + CPF + " , RG " + RG ) ;
else
System . o u t . p r i n t l n ( "O S r . " + nome + " n a s c e u no ano " +
a n o D e N a s c im e n t o +
" . CPF : " + CPF + " , RG " + RG ) ;
}
}
c l a s s Aluno e x t e n d s P e s s o a
{
private String curso ;
private int anoDeIngresso ;
v o i d imprimeDados ( )
{
s u p e r . imprimeDados ( ) ;
System . o u t . p r i n t l n ( " I n g r e s s o u no c u r s o " + c u r s o + " em " +
anoDeIngresso ) ;
}
}
c l a s s P r o f e s s o r extends Pessoa
{
private String departamento ;
p r i v a t e i n t anoDeAdmisso ;
v o i d imprimeDados ( )
{
s u p e r . imprimeDados ( ) ;
System . o u t . p r i n t l n ( " I n g r e s s o u no d e p t . " + d e p a r t a m e n t o + " em " +
anoDeAdmisso ) ;
}
}
c l a s s ProfessorDoutor extends P r o f e s s o r
{
p r i v a t e i n t anoDeObtenoDoutorado ;
private String instituioDoDoutorado ;
v o i d imprimeDados ( )
{
s u p e r . imprimeDados ( ) ;
System . o u t . p r i n t l n ( " D o u t o r a d o o b t i d o em " + i n s t i t u i o D o D o u t o r a d o
+ " em " + a n o D e O b t e n o D o u t o r a d o ) ;
}

117

118

CAPTULO 20. HERANA

Um banco de dados da universidade pode armazenar objetos do tipo Pessoa da seguinte forma:
c l a s s ListaDePessoasDaUSP
{
P e s s o a [ ] membrosDaUSP ;
L i s t a D e P e s s o a s D a U S P ( i n t tamanho )
{
membrosDaUSP = new P e s s o a [ tamanho ] ;
}
/ / m t o d o s p a r a a c r e s c e n t a r e r e m o v e r p e s s o a s da l i s t a de p e s s o a s
void l i s t a T o d o s ( )
{
int i ;
f o r ( i = 0 ; i < membrosDaUSP . l e n g t h ; i ++)
membrosDaUSP [ i ] . imprimeDados ( ) ;
}
/ / demais mtodos . . .
}

Note que para o mtodo listaTodos, no interessa qual o tipo especfico de cada pessoa (aluno, professor,
professor doutor) uma vez que ele manipula apenas os atributos da superclasse Pessoa.

20.4 Hierarquia de Classes


Quando um programa possui uma srie de classes relacionadas atravs de herana, dizemos que temos uma
hierarquia de classes.
Apresentamos na figura 20.2 uma hierarquia de classes para representar os diversos tipos de seres vivos.

Figura 20.2: Hierarquia de classes representando os seres vivos

119

20.5. RELACIONAMENTO UM

20.5 Relacionamento um
Nem sempre fcil determinarmos qual hierarquia de classes devemos utilizar. A relao superclasse-subclasse
deve necessariamente ser um relacionamento do tipo " um", ou seja se B subclasse de A ento todo B um A.
Em termos mais concretos, no exemplo dos seres vivos, Animal um SerVivo, e mais, todo animal um
ser vivo. No existe nenhum animal que no seja um ser vivo. Ento o relacionamento superclasse-subclasse
pode ser apropriado.
Outra possibilidade seria ter uma hierarquia como a seguinte:

Figura 20.3: Hierarquia errada

A principio, esta pode parecer uma hierarquia aceitvel. Mas na verdade ela est ERRADA. No podemos
dizer que "um reino um ser vivo", no faz sentido, no podemos dizer que "um filo um reino"porque no .
Ento a hierarquia no est boa.

20.6

Resumo

uma classe pode herdar de outra seus atributos e mtodos


uma subclasse pode estender a funcionalidade de sua superclasse acrescentando novos atributos e mtodos
Mas, e se uma subclasse implementar um mtodo com assinatura idntica a um mtodo da superclasse?
Neste caso, quem prevalece o mtodo da subclasse e dizemos que o mtodo da subclasse se sobrepe ("overrides") ao mtodo da superclasse.

20.7 Exerccios
1. Retornando hierarquia de classes apresentada na figura 20.2, pense em quais mtodos e atributos deveriam estar presentes nas classes superiores da hierarquia e quais deveriam estar nas partes inferiores da
hierarquia.

120

CAPTULO 20. HERANA

Captulo 21

Javadoc
Quais novidades veremos nesta aula?
Documentao com javadoc

21.1 Javadoc
Vimos nas ltimas aulas que um conceito fundamental em programao orientada a objeto a separao clara
entre implementao e interface. Ou seja, um programador que v usar objetos de uma classe deve se ater a
poro pblica da mesma, desprezando detalhes de implementao e as pores privadas (que no estariam
acessveis de qualquer forma).Deste modo, passa a ser natural a exigncia de documentao de boa qualidade
que permita ao usurio de uma classe saber tudo o que precisa sem que necessite ler o cdigo que a implementa.
A entra o javadoc.
O javadoc um programa que permite extrair de um arquivo com cdigo Java a sua documentao (os
comentrios). Essa documentao ento formatada em html (a mesma linguagem que descreve as pginas
web) de modo a facilitar a sua consulta. Assim possvel consultar a documentao de uma classe sem as
distraes presentes sempre que esta est misturada ao cdigo. Um exemplo disso que, em sua configurao
padro, o javadoc processa apenas a documentao das partes pblicas de seu cdigo, omitindo tudo o que e
privado.
Para facilitar a vida do programa javadoc existem algumas convenes que devem ser seguidas. A primeira
que apenas comentrios iniciados por /** (e terminados por */) sero processados. Tambm o comentrio de
cada parte pblica deve preced-la imediatamente. Vejamos um exemplo simples.
p u b l i c c l a s s Quadrado implements F i g u r a G e o m e t r i c a
{
p r i v a t e double l a d o ;
private String cor ;
p u b l i c Quadrado ( d o u b l e l , S t r i n g c )
{
lado = l ;

121

122

CAPTULO 21. JAVADOC


cor = c ;
}
p u b l i c double c a l c u l a A r e a ( )
{
return lado lado ;
}
p u b l i c v o i d mudaCor ( S t r i n g c )
{
cor = c ;
}

As partes pblicas no cdigo acima so:


1. A prpria classe, ou seja todo mundo pode criar objetos baseados nela;
2. O construtor;
3. Os mtodos calculaArea e calculaPerimetro.
Cada um desses tens deveria ser antecedido por um comentrio explicando qual sua funo e como ele
deve ser usado. Lembrando as convenes de como demarcar os comentrios descritas acima teramos:
/
Uma c l a s s e p a r a r e p r e s e n t a r q u a d r a d o s .
/
p u b l i c c l a s s Quadrado implements F i g u r a G e o m e t r i c a
{
p r i v a t e double l a d o ;
private String cor ;
/
Construtor
E x i g e o c o m p r i m e n t o do l a d o e a c o r do q u a d r a d o .
/
p u b l i c Quadrado ( d o u b l e l , S t r i n g c )
{
lado = l ;
cor = c ;
}
/
C a l c u l a a r e a do q u a d r a d o b a s e a d a no s e u l a d o .
/
p u b l i c double c a l c u l a A r e a ( )
{
return lado lado ;
}
/
A l t e r a a c o r do q u a d r a d o p a r a a c o r r e p r e s e n t a d a na
cadeia c .

21.1. JAVADOC

123

/
p u b l i c v o i d mudaCor ( S t r i n g c )
{
cor = c ;
}
}

Uma outra caracterstica interessante do javadoc que possumos alguns marcadores especiais para que
ele possa pegar informaes relevantes nos comentrios e format-las de modo especial. Os marcadores mais
importantes so:
Marcadores para comentrios de classes:
@author: Descreve o autor do cdigo;
@version: Usado para guardar informao sobre a verso, como seu nmero e data de ltima
alterao.
Marcadores para comentrios de mtodos:
@param: usado para descrever os parmetros, geralmente na forma:
@param nome-do-parmetro descrio
@return: serve pra descrever o que o mtodo retorna.
Marcador geral: @see Pode ser usado em qualquer lugar para referenciar uma outra classe ou um mtodo
de outra classe assume geralmente uma das duas forma a seguir.
@see nome-da-classe
@see nome-da-classe#nome-do-mtodo
Se usarmos os marcadores descritos acima na nossa classe Quadrado, teremos:
/
Uma c l a s s e p a r a r e p r e s e n t a r q u a d r a d o s .
@author P a u l o S i l v a
@ v e r s i o n 1 . 0 , a l t e r a d a em 1 0 / 0 6 / 2 0 0 3
@see F i g u r a G e o m e t r i c a
/
p u b l i c c l a s s Quadrado implements F i g u r a G e o m e t r i c a
{
p r i v a t e double l a d o ;
private String cor ;
/
Construtor
@param l d o u b l e r e p r e s e n t a n d o o c o m p r i m e n t o d o s l a d o s
@param c S t r i n g com o nome da c o r da f i g u r a
/
p u b l i c Quadrado ( d o u b l e l , S t r i n g c )
{
lado = l ;
cor = c ;
}

124

CAPTULO 21. JAVADOC

/
C a l c u l a a r e a do q u a d r a d o b a s e a d a no s e u l a d o
@param No h p a r m e t r o s
@return r e a computada
/
p u b l i c double c a l c u l a A r e a ( )
{
return lado lado ;
}
/
A l t e r a a c o r do q u a d r a d o .
@param c S t r i n g com o nome da nova c o r
@return No h r e t o r n o
/
p u b l i c v o i d mudaCor ( S t r i n g c )
{
cor = c ;
}
}

Na figura 21.1 apresentada a documentao gerada pelo Javadoc para a classe Quadrado.
claro que para o marcador @see funcionar, voc tambm deve documentar a interface usando os padres
de javadoc. Ao documentar a interface voc pode usar os mesmos marcadores usados para classe.
Bom, agora que temos no nosso cdigo documentado de forma adequada, como podemos gerar a documentao em html? Para isso basta ir ao diretrio com os arquivos .java e digitar
javadoc -version -author -d doc *.java
A documentao ser ento gerada e os arquivos resultantes sero colocados dentro do sub-diretrio doc
do diretrio atual. claro que o nome desse diretrio pode ser alterado mudando-se a palavra que segue o -doc
presente acima.
Por fim, podemos tambm documentar as pores privadas de nossas classes. Para forar o javadoc a gerar
documentao tambm para a parte privada basta acrescentar o parmetro -private na linha comando acima.
Obs: os comentrios de javadoc podem conter tags em html.

125

21.1. JAVADOC

Figura 21.1: Documentao gerada pelo Javadoc

126

CAPTULO 21. JAVADOC

Captulo 22

O C que h em Java
Quais novidades veremos nesta aula?
Veremos como escrever programas na linguagem C
a partir de nossos conhecimentos de Java.

22.1 O C que h em Java


Veremos nessa aula como so os programas na linguagem C e como podemos escrev-los usando o que aprendemos em nosso curso de introduo computao. Em resumo podemos pensar que um programa em C
uma nica classe Java sem a presena de atributos e composta apenas com mtodos estticos. Fora isso o resto
perfumaria. Vamos pensar um pouco quais so as conseqncias da frase acima:
Como h apenas uma classe e no h atributos no possvel organizar o programa como diversos objetos,
eventualmente pertencentes a classes diferentes, interagindo.
Como no h atributos s existem dois tipos de variveis: os parmetros e as variveis locais s funes.
Como no h classes e objetos de verdade, todas as variveis so de tipos primitivos: int, double ou
char. Pelo menos h tambm a idia de array, ou vetor, e matrizes em C.
Em C no h o tipo boolean. No seu lugar usamos inteiros com o 0 representando falso e qualquer
nmero no-nulo representando verdadeiro. Note que as expresses lgicas passam ento a gerar valores
inteiros como resultados.
Esses pontos j so interessantes o suficiente para vermos o que acontece. Consideremos o primeiro exemplo visto neste livro: o conversor de temperaturas. Voc lembra que ele era um objeto sem atributos? Vejamos
o seu cdigo (adicionamos um main e os identificadores de acesso):
127

128

CAPTULO 22. O C QUE H EM JAVA

public c l a s s Conversor
{
s t a t i c double c e l s i u s P a r a F a h r e n h e i t ( double c )
{
return 9.0 c / 5.0 + 3 2 . 0 ;
}
s t a t i c double f a h r e n h e i t P a r a C e l s i u s ( double f )
{
return 5.0 ( f 3 2 . 0) / 9 . 0 ;
}
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s )
{
double f a r , c e l ;
System . o u t . p r i n t ( " De um t e m p e r a t u r a em F a h r e n h e i n t : " ) ;
f a r = SavitchIn . readDouble ( ) ;
cel = fahrenheitParaCelsius ( far );
System . o u t . p r i n t l n ( "A t e m p e r a t u r a em C e l s i u s : " + c e l ) ;
System . o u t . p r i n t ( " De um t e m p e r a t u r a em C e l s i u s : " ) ;
c e l = SavitchIn . readDouble ( ) ;
far = celsiusParaFahrenheit ( cel );
System . o u t . p r i n t l n ( "A t e m p e r a t u r a em F a h r e n h e i t : " + f a r ) ;
}
}

Vejamos como ficaria esse programa na linguagem C:


/ Sempre c o l o q u e a p r o x i m a l i n h a no i n i c i o do programa . /
/ E l a p e r m i t e que v o c i m p r i m a na t e l a e l e i a do t e c l a d o . /
# i n c l u d e < s t d i o . h>
/
/
/
/
/

Como nao ha c l a s s e s
Do mesmo modo , como
precisamos escrever
Por f i m nao e x i s t e m
e l e s tambem sumiram .

s i m p l e m e n s t e apagamos a r e f e n c i a a e l a . /
t o d o s o s m e t o d o s s a o e s t a t i c o s nao
/
isso .
/
e s p e c i f i c a d o r e s de a c e s s o em C , l o g o
/
/

double c e l s i u s P a r a F a h r e n h e i t ( double c )
{
return 9.0 c / 5.0 + 3 2 . 0 ;
}
double f a h r e n h e i t P a r a C e l s i u s ( double f )
{
return 5.0 ( f 3 2 . 0) / 9 . 0 ;
}
/ V e j a que a c a r a da main mudou . Agora e l a no r e c e b e nada /
/ e d e v o l v e um i n t e i r o .
/
i n t main ( )
{
double f a r , c e l ;
/ Oba , i m p r i m i r f i c o u m a i s f a c i l : o comando e m a i s c u r t o . /
p r i n t f ( " De um t e m p e r a t u r a em F a h r e n h e i n t : " ) ;
/ A l e i t u r a tambem mudou , v e j a d e t a l h e s a b a i x o . /

22.2. DETALHES DE ENTRADA E SADA

129

s c a n f ( "%l f " , &f a r ) ;


cel = fahrenheitParaCelsius ( far );
p r i n t f ( "A t e m p e r a t u r a em C e l s i u s : %f \ n " , c e l ) ;
p r i n t f ( " De um t e m p e r a t u r a em C e l s i u s : " ) ;
s c a n f ( "%l f " , &c e l ) ;
far = celsiusParaFahrenheit ( cel );
p r i n t f ( "A t e m p e r a t u r a em F a h r e n h e i t : %f \ n " , f a r ) ;
/ Para n o s e s s e r e t o r n o nao s e r v e p a r a nada , e um t o p i c o a v a n c a d o . /
return 0;
}

22.2

Detalhes de entrada e sada

Alm do sumio das classes, dos indicadores de acesso e dos termos static (pois todas as funes so assim)
dos programas em C, uma outra mudana bastante visvel que os comandos para escrever na tela e para leitura
do teclado mudam bastante. No lugar do System.out.println aparece o printf e no lugar dos mtodos da
classe SavitchIn usamos o scanf. A forma de us-los tambm muda um pouco:
1. printf: Imprime na tela. O primeiro parmetro deve ser sempre uma string (texto entre aspas). Diferente do que ocorria com Java, no podemos usar a soma para concatenar cadeias. Como apresentar
ento variveis no meio a string que ser impressa pelo printf? Usamos nesse caso uns marcadores especiais para "deixar espao"para imprimir o valor da varivel e em seguida passamos estas variveis como
parmetro. Vejamos um exemplo.
p r i n t f ( " E s s e e i n t e i r o %d , e s s e d o u b l e %f , e o u l t i m o um c h a r %c " ,
u m I n t e i r o , umDouble , umChar ) ;

Caso desejemos que o printf pula de linha ao final, devemos adicionar um \n no final da string do
printf:
p r i n t f ( " E s s e e i n t e i r o %d , e s s e d o u b l e %f , e o u l t i m o um c h a r %c \ n " ,
u m I n t e i r o , umDouble , umChar ) ;

Vale a pena consultar um manual de C para ver o printf em ao. Ele um comando mais poderoso do
que parece.
2. scanf: Para ler valores do teclado usamos o scanf. Ele tambm recebe uma string com marcadores
semelhantes do printf (a principal diferena que para ler um double usamos %lf e no %f). Depois
aparecem as variveis que devem ser lidas antecedidas de um &. Por exemplo se queremos ler um inteiro
e um double fazemos:
s c a n f ( "%d%l f " , &u m I n t e i r o , &umDouble ) ;

22.3

Declarao de variveis

Em C, comum que a declarao de todas as variveis seja no incio da funo. Isso porm no obrigatrio
(j foi, no mais). Para declarar vetores em C a sintaxe mais simples do que em Java. Por exemplo se
queremos que a varivel a seja um vetor de 100 inteiros basta:

130

CAPTULO 22. O C QUE H EM JAVA

int a [100];

A mesma coisa para matrizes:


int a [100][100];

22.4

Parmetros de funes

Assim como em Java, os parmetros que so tipos primitivos modificados dentro da funo no se refletem fora
dela. J se alterarmos o contedo de um vetor ele se reflete fora. Uma coisa interessante que possvel pedir
ao C que ele permita que a alterao de parmetros que so de tipo primitivo reflita-se fora da funo. Para isso
deve-se anteceder o parmetro de um asterisco em toda a funo (inclusive na declarao do parmetro). Ao
chamar a funo, a varivel que queremos alterar deve estar precedida de um &.
# i n c l u d e < s t d i o . h>
/ T r o c a d u a s v a r i v e i s de l u g a r /
v o i d swap ( i n t a , i n t b )
{
i n t temp ;
temp = a ;
a = b ;
b = temp ;
}
i n t main ( )
{
int c , d ;
c = 1;
d = 2;
swap(&c , &d ) ;
p r i n t f ( " c = %d , d = %d " , c , d ) ;
}

Outra mudana que os colchetes de parmetros que so vetores e matrizes devem vir aps os seus nomes
(e no antes como em Java). Alm disso, se o parmetro um matriz, voc deve informar na declarao da
funo qual o nmero de linhas que a matriz tem. Por exemplo
v o i d umaFuncao ( i n t umVetor [ ] , i n t u m a M a t r i z [ 1 0 0 ] [ ] )

22.5 Um ltimo exemplo


Vejamos um ltimo exemplo de programa em C. Queremos escrever um programa que l uma seqncia de
inteiros estritamente positivos terminada por zero e imprime o nmero e imprime a sua mediana.
# i n c l u d e < s t d i o . h>
v o i d s e l e c a o D i r e t a ( i n t numeros [ ] , i n t f i m )
{
i n t i , j , minimo , temp ;
for ( i = 0 ; i < fim 1 ; i = i + 1)

22.5. UM LTIMO EXEMPLO


{
/ I n i c i a l m e n t e o menor e l e m e n t o j a v i s t o e o p r i m e i r o e l e m e n t o . /
minimo = i ;
for ( j = i + 1 ; j < fim ; j = j + 1)
{
i f ( numeros [ j ] < numeros [ minimo ] )
minimo = j ;
}
/ C o l o c a o menor e l e m e n t o no i n i c i o do subv e t o r a t u a l . /
temp = numeros [ i ] ;
numeros [ i ] = numeros [ minimo ] ;
numeros [ minimo ] = temp ;
}
}
i n t main ( )
{
/ A c e i t a no maximo 100 numeros no v e t o r . /
i n t numeros [ 1 0 0 ] ;
i n t i = 1;
/ Le o v e t o r . /
do
{
i ++;
s c a n f ( "%d " , &numeros [ i ] ) ;
} w h i l e ( numeros [ i ] > 0 ) ;
/ Ordena p a r a e n c o n t r a r a mediana . /
s e l e c a o D i r e t a ( numeros , i ) ;
/ Agora f i c o u f c i l . /
p r i n t f ( "A m e d i a n a e : %d \ n " , numeros [ ( i 1 ) / 2 ] ) ;
/ O t a l return i n u t i l . /
return 0;
}

131

132

CAPTULO 22. O C QUE H EM JAVA

Apndice A

Utilizando o Dr. Java


A.1

Introduo

DrJava um ambiente de desenvolvimento para a linguagem Java. Por ser ele mesmo escrito em Java, pode
ser usado em diversos ambientes, como, por exemplo, Linux, Windows e Mac OS. Um ambiente de desenvolvimento (tambm conhecido por IDE, de Integrated Development Environment) um conjunto de ferramentas
integradas que auxiliam a construo de programas.
O DrJava se encontra em desenvolvimento, por isso alguns recursos desejveis ainda no esto disponveis.
Entretanto, os recursos mais simples que ele fornece j so apropriados para os nossos objetivos nesta disciplina.
Planejamos ento utilizar o DrJava para escrevermos nossos programas Java deste semestre.

Objetivos
Esperamos com esta aula introduzir o uso do DrJava. O contedo da aula limitado e especfico, suficiente para
que voc posteriormente seja capaz de conhecer melhor esta ferramenta por conta prpria. Recomendamos para
isso a consulta de manuais e outros documentos, no necessariamente sobre DrJava apenas. As descobertas
pelo prprio uso e atravs de dicas de colegas tambm so incentivadas.
Nesta aula voc aprender a utilizar o DrJava para
escrever, compilar, manipular e depurar classes/objetos simples;
gravar e reutilizar os arquivos que descrevem seus objetos.
Questes mais gerais sobre uso do computador, como impresso do cdigo fonte e manipulao de arquivos
fora do DrJava, dependem muito do ambiente que voc utiliza e por isso no so abordados nesta aula. No
IME esto disposio dos alunos dois laboratrios que possuem ambientes bem distintos: as salas Pr-Aluno
<http://www.linux.ime.usp.br> e o CEC. Sugerimos que voc consulte os documentos de ajuda disponibilizados
pela prpria administrao de cada laboratrio para resolver esse tipo de dvida.

A.1.1

Como obter, instalar e executar o DrJava

Essas informaes estaro disponveis no stio da disciplina.


133

134

A.2

APNDICE A. UTILIZANDO O DR. JAVA

Conversor de Temperatura simples

Como exemplo inicial, vamos construir a classe Conversor vista em aula. Lembrando, cada objeto dessa
classe converte apenas a temperatura de 40 graus celsius para a correspondente em graus fahrenheit. Para isso,
ao receber a mensagem celsiusParaFahrenheit, ele devolve a temperatura em fahrenheit equivalente a 40
graus celsius.

Editando o cdigo-fonte num arquivo


Vejamos o que o DrJava nos oferece para criarmos a classe. Ao iniciar o ambiente DrJava, abre-se uma janela
parecida com a seguinte.

O painel de definies, indicado na figura acima, um editor de textos. nele que digitaremos o cdigo
Java que define a classe Conversor. Ele se parece muito com um editor de textos comum, exceto que possui
alguns recursos para facilitar a digitao de cdigo. Em particular, o comportamento das teclas <Enter> e
<Tab> favorece a indentao do cdigo. Outro recurso til a colorao e destaque do texto.
Precisamos criar um arquivo novo para conter o cdigo da nossa classe. Para isso, bastaria escolher a
opo New do menu File. Porm, quando abrimos o DrJava, um novo arquivo sem nome j foi criado, ento
podemos us-lo nesse momento (em vez de criar um novo). Sendo assim, digite o seguinte cdigo no painel de
definies.
c l a s s Conversor
{
int celsiusParaFahrenheit ()
{
r e t u r n 9 40 / 5 + 3 2 ;
}
}

A.2. CONVERSOR DE TEMPERATURA SIMPLES

135

Ao digitar, note os recursos mencionados que ajudam a programao (principalmente o comportamento das
teclas <Enter> e <Tab>).

Gravando e reutilizando o arquivo


Vamos agora gravar o arquivo no disco. Escolha o menu File (clicando com o mouse ou usando as teclas de
atalho, que nesse caso a combinao <Alt>+<F>) e escolha o item Save. Como o arquivo ainda no tem
nome, estaremos na verdade acionando a opo Save as.... Por isso, surgir um dilogo para definirmos a
localizao e o nome do arquivo, como mostra a seguinte figura.

Podemos determinar a localizao manipulando a combo box com rtulo Save In: (no topo do dilogo) e
escolhendo um diretrio na caixa abaixo dela.
Ou podemos deixar a localizao como est. Desse modo, provavelmente o arquivo ser gravado no diretrio de onde o DrJava foi chamado.
Tambm precisamos escolher o nome do arquivo. Em algumas ocasies, este deve ser obrigatoriamente
idntico ao nome da classe, mais o sufixo .java. No o nosso caso, mas mesmo assim vamos chamar o arquivo
de Conversor.java. Como j digitamos o cdigo da classe, o DrJava preencheu o nome do arquivo no input field
de rtulo File Name: com o nome da classe. Note tambm que ele no acrescentou o sufixo .java no nome,
isso ser feito implicitamente quando finalizarmos (mas no h problema em digitar o sufixo mesmo assim).
Para confirmar a gravao, basta clicar no boto Save. As modificaes futuras podem ser gravadas com o
comando Save, sem precisar escolher o nome do arquivo novamente.
Com os arquivos das classes gravados em disco, podemos querer reutiliz-los no futuro. No DrJava, basta
escolhermos a opo Open do menu File, e um dilogo permitir que voc escolha o arquivo que deseja abrir
novamente ( semelhante ao processo do Save as...).

Compilando a classe
Acabamos de definir a nossa classe, precisamos agora compilar para que possamos us-la. No menu Tools,
temos duas opes para fazer isso, Compile All Documents e Compile Current Document. Como s temos
um documento aberto (Conversor.java), qualquer uma das opes serve. Escolha ento Compile Current
Document.
Com isso compilaremos a nossa classe. Note que no painel inferior da janela, a guia Compiler Output se
abre mostrando algumas mensagens. Se tudo der certo, a nossa janela se parecer com a seguinte.

136

APNDICE A. UTILIZANDO O DR. JAVA

Usando a classe
Podemos finalmente usar a guia Interactions, que chamaremos de janela do interpretador, para criar e usar
objetos da classe Conversor. Essa janela recebe comandos num prompt, e a sintaxe desses comandos muito
parecida com a da linguagem Java.
Clique ento em Interactions, e digite o seguinte.
C o n v e r s o r conv = new C o n v e r s o r ( ) ;
conv . c e l s i u s P a r a F a h r e n h e i t ( )

A ausncia de ; no final da linha do comando faz com que o interpretador imprima o valor devolvido pelo
comando.
A janela do interpretador dever se parecer com a figura abaixo.

A.3

Tratando erros

Utilizaremos agora a classe Conversor4 vista em aula para mostrarmos alguns outros recursos do DrJava. Para
quem no lembra, objetos dessa classe convertem temperaturas entre graus Celsius e Fahrenheit fornecendo os
seguintes mtodos.
* double celsiusParaFahrenheit (double c): recebe uma temperatura c em graus celsius e devolve
a temperatura correspondente em graus fahrenheit. * double fahrenheitParaCelsius (double f): recebe
uma temperatura f em graus fahrenheit e devolve a temperatura correspondente em graus celsius.
Para esta aula dirigida, porm, usaremos um cdigo um pouco diferente em relao ao dado em aula normal.

A.3. TRATANDO ERROS

137

Erros no cdigo
Feche o arquivo Conversor.java usando a opo Close do menu File e crie um novo arquivo (na verdade, como
havia apenas um arquivo aberto, um novo criado automaticamente).
Digite nesse arquivo o cdigo abaixo (h erros intencionais nele). Voc pode tambm usar o recurso de
copiar e colar (copy and paste).
c l a s s Conversor4
{
double c e l s i u s P a r a F a h r e n h e i t ( double c )
{
double f = 9 . 0 c / 5 . 0 + 32.0
return f ;
}
double f a h r e n h e i t P a r a C e l s i u s ( double f )
{
double c = 9 . 0 ( f 3 2 . 0 ) / 9 , 0 ;
return c ;
}
}

Grave o arquivo e compile. Como o cdigo contm erros, o compilador no ter sucesso e imprimir
algumas mensagens. Algo como mostra a figura abaixo.

O primeiro erro pode ser eliminado acrescentando-se um ; no final da linha 5. Veja que o prprio compilador sugere isso.
J a descrio do segundo erro pode ser um pouco confusa. importante saber que o compilador capaz
de encontrar erros no cdigo, mas nem sempre pode determinar a causa exata. Nesses casos, as mensagens de
erro apenas do pistas para descobrirmos o que est errado (algumas vezes pistas falsas).
O segundo erro uma vrgula no lugar de um ponto, no final da linha 10.
H outros tipos de erro os quais o compilador no tem condies de detectar. Um exemplo o erro na
frmula de converso da linha 10. H um 9.0 onde deveria estar um 5.0.

138

APNDICE A. UTILIZANDO O DR. JAVA

Vimos em aula uma maneira de detectarmos tais erros atravs de testes. Mas depois de detectarmos, precisamos descobrir a causa deles. Veremos a seguir uma ferramenta til para essa tarefa.
Mas antes corrija os erros e compile.

Depurador
Depurador (debugger) uma ferramenta que nos ajuda a corrigir erros (bugs) de programas. O depurador
do DrJava oferece apenas recursos bsicos: pontos de parada (breakpoints), execuo passo a passo (step)
e inspeo simples de variveis (watch). Mesmo assim, a classe Conversor4 no complexa o suficiente
para justificar a aplicao do depurador, vamos utiliz-la apenas para demonstrar rapidamente cada um desses
recursos.
Para ativar o depurador, escolha a opo Debug Mode do menu Debugger. Ao fazer isso, o painel de
depurao exibido na janela principal.

Comearemos selecionando um ponto de parada no cdigo do Conversor4. Isso feito no painel de


definies, posicionando o cursor na linha desejada e escolhendo a opo Toggle Breakpoint on Current
Line do menu Debugger.
O ponto de parada faz com que a execuo do programa seja temporariamente interrompida exatamente
antes da linha ser executada. A partir da, para continuar a execuo, deve-se usar os comandos de "passo a
passo"(step into, step over, step out, resume). O que cada comando faz pode ser encontrado na seo Documentation da pgina do DrJava <http://drjava.sourceforge.net>
Posicione ento o cursor do painel de definies na linha 10 do Conversor4, e insira um ponto de parada
(a linha ficar com um destaque vermelho). Para que o ponto de parada seja usado, temos que fazer com que o
mtodo seja executado. Para isso digite o seguinte na janela do interpretador.
C o n v e r s o r 4 c4 = new C o n v e r s o r 4 ( ) ;
c4 . f a h r e n h e i t P a r a C e l s i u s ( 4 2 )

A.3. TRATANDO ERROS

139

A execuo do mtodo ser interrompida antes da linha 10 ser executada. O destaque azul da linha indica
isso. Para continuar a execuo passo a passo (linha a linha), execute o comando step over algumas vezes
(pressionando a tecla <F11>).
Dessa forma, possvel constatar quais trechos de cdigo so usados numa execuo em particular.
Um outro recurso bastante til, que deve ser usado em conjunto com esses que acabamos ver, a inspeo
de valores de variveis (watch).
Esse recurso nos informa o valor de certas variveis durante a execuo passo a passo. Para isso, necessrio preencher a coluna Name da tabela da guia Watches com os nomes das variveis que se deseja inspecionar
(uma varivel em cada linha da tabela). Basta clicar numa clula da coluna Name, digitar o nome da varivel e
pressionar <Enter>.
Ento faa isso para as variveis c e f. Teremos algo como a prxima figura.

Repita a execuo passo a passo descrita anteriormente e observe o que ocorre com a tabela.
Dica: o interpretador armazena os ltimos comandos digitados na janela. Para acess-los, pressione as
setas para cima e para baixo do teclado. Esse recurso se chama History, e possui algumas opes teis no menu
Tools.

140

APNDICE A. UTILIZANDO O DR. JAVA

Referncias Bibliogrficas
[1] Philippe Breton, Histria da Informtica, Editora Unesp, 1987
[2] Walter Savitch, Java, An Introduction to Computer Science & Programming, second edition, Prentice Hall,
2001
[3] Samuel N. Kamin, M. Dennis Mickunas and Edward M. Reingold, An Introduction to Computer Science
Sing Java, McGraw-Hill, 1998

141

Вам также может понравиться