Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas

Ciência da Computação com Java e Orientação a Objetos - Apostilas - Informática Part1, Notas de estudo de Informática

Apostilas de Informática sobre o estudo da Ciência da Computação com Java e Orientação a Objetos, História da Computação, Conversor de Temperaturas, Métodos com Vários Parâmetros.

Tipologia: Notas de estudo

2013

Compartilhado em 26/06/2013

Ipanema27
Ipanema27 🇧🇷

4.5

(130)

484 documentos

1 / 65

Documentos relacionados


Pré-visualização parcial do texto

Baixe Ciência da Computação com Java e Orientação a Objetos - Apostilas - Informática Part1 e outras Notas de estudo em PDF para Informática, somente na Docsity! UNIVERSIDADE DE SÃO PAULO INSTITUTO DE MATEMÁTICA E ESTATÍSTICA Departamento de Ciência da Computação Introdução à Ciência da Computação com Java e Orientação a Objetos 1a edição Alfredo Goldman Fabio Kon Paulo J. S. Silva Editado e Revisado por: Raphael Y. de Camargo Ficha Catalográfica Elaborada pela Biblioteca do IME-USP QA724 K82i Kon, Fabio; Goldman, Alfredo; Silva P. J. S. Introdução à ciência da computação com Java e orientação a objetos, editado e revisado por Raphael Y. de Camargo. 1. ed. São Paulo : IME-USP, 2006. 190p. ISBN: 85-88697-10-6 1. Linguagem de Programação 2. Programação orientada a objeto 3. Java I. Goldman, Alfredo II. Silva, Paulo J. S. III. Camargo, Raphael Y. de, ed. e rev. IV. Universidade de São Paulo, Instituto de Matemática e Estatística. Departamento de Ciência da Computação. CDD 600 iii A nossas esposas e filhos, fonte de força e alegria em nossas vidas. iv v Agradecimentos Este livro não seria possível sem a colaboração de inúmeros alunos e profes- sores 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 responsáveis por inúmeras contribuições. O apêndice sobre o Dr. Java foi preparado pelo Leo. Fabiano Mitsuo Sato, George Henrique Silva e Igor Ribeiro Sucupira foram monitores da disciplina também em 2003 e colaboraram com alguns exercícios. Raphael Y. de Camargo realizou um excelente trabalho na edição e revisão do livro além de colaborar com alguns exercícios. O Prof. João Eduardo Ferreira, nosso colega no ensino da disciplina de introdução, o Prof. Valdemar Setzer, nosso experiente e sábio colega de departamento, e o Prof. Marcos Chaim, da USPLeste, nos deram inúmeras sugestões úteis que, sempre que possível, foram incorporadas ao texto final. Agradecemos ao Prof. Walter Savitch da Universidade da California em San Diego por ter autorizado o uso de sua classe para entrada de dados. Agrade- cemos também a Giuliano Mega pela diagramação da capa e a Stefano Mega pelos objetos nadando na xícara de Java. Finalmente, agradecemos aos alunos e professores que não foram citados mas que deram sugestões e nos incentivaram a escrever este livro. viii SUMÁRIO 10 Mergulhando no while 63 10.1 Um pouco mais sobre primos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 10.2 Uma biblioteca de funções matemáticas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 10.3 do...while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 11 Caracteres e Cadeias de Caracteres 69 11.1 Um tipo para representar caracteres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 11.2 Cadeias de caracteres (Strings) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 12 A Memória e as Variáveis 75 12.1 A Memória do Computador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 12.2 O que são as Variáveis? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 13 Manipulando Números Utilizando Diferentes Bases 79 13.1 Sistemas de numeração . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 13.2 Conversão entre sistemas de numeração . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 14 Arrays (vetores) 83 14.1 Criação de programas Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 15 for, leitura do teclado e conversão de Strings 89 15.1 O comando for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 15.2 Leitura do teclado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 15.3 Conversão de String para números . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 16 Laços Encaixados e Matrizes 95 16.1 Laços encaixados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 16.2 Matrizes (arrays multidimensionais) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 16.3 Exemplo: LIFE, o jogo da vida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 17 Busca e Ordenação 103 17.1 Busca . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 17.2 Pondo ordem na casa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 18 Busca Binária e Fusão 107 18.1 Busca binária . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 18.2 Complexidade Computacional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 18.3 Fusão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 19 Construtores e Especificadores de Acesso 111 19.1 Construtores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 19.2 Especificadores de acesso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 SUMÁRIO ix 20 Interfaces 117 20.1 O conceito de interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 20.2 Um primeiro exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 20.3 Implementando mais de uma interface por vez . . . . . . . . . . . . . . . . . . . . . . . . . . 121 20.4 Um exemplo mais sofisticado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 20.5 A importância de interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 21 Herança 131 21.1 O Conceito de herança . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 21.2 Terminologia de herança . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 21.3 Implementação de herança na linguagem Java . . . . . . . . . . . . . . . . . . . . . . . . . . 132 21.4 Hierarquia de classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 21.5 Relacionamento “é um” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 21.6 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 22 Javadoc 137 23 O C Que Há em Java 143 23.1 O C que há em Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 23.2 Detalhes de entrada e saída . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 23.3 Declaração de variáveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 23.4 Parâmetros de funções . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 23.5 Um último exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 A Utilizando o Dr. Java 151 A.1 Conversor de Temperatura simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 A.2 Tratando erros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 B Desenvolvimento Dirigido por Testes 159 B.1 O Exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 Bibliografia 175 x SUMÁRIO Prefácio Caros leitores, sejam bem-vindos ao maravilhoso mundo da Ciência da Computação. Com este livro, vocês terão a oportunidade de aprender os elementos básicos da programação de computadores e terão contato com alguns dos conceitos fundamentais da Ciência da Computação. Este livro é resultado da experiência dos autores na disciplina de Introdução à Ciência da Computação ministrada no IME/USP utilizando orientação a objetos e a linguagem Java de 2003 a 2006. Desde 2005, esta abordagem também é aplicada na USPLeste com os 180 alunos do curso de Sistemas de Informação. Influenciada pelo método proposto pela ACM (Association for Computing Machinery) e pelo IEEE (Institute of Electrical and Electronics Engineers) em seu currículo Objects-first, nossa abordagem evita o problema de se ensinar a programar sem o uso de objetos para depois exigir do estudante uma mudança de paradigma com a introdução de objetos. Elimina-se assim a necessidade de dizer “esqueça a forma que programamos até agora; agora vamos aprender o jeito correto”. Apresentando os conceitos de orientação a objetos desde o início do ensino de programação, a abordagem adotada aqui permite que o aluno inicie sua formação em programação de forma equilibrada. Aprendendo con- ceitos tanto algorítmicos quanto estruturais ao mesmo tempo em que toma contato com práticas fundamentais de programação como testes automatizados e o uso de nomes claros para os elementos do código, o leitor obtém uma visão básica porém ampla do que é mais importante para o desenvolvimento de software. Esperamos que este livro seja útil tanto para alunos de cursos superiores de Informática quanto para pro- fissionais do mercado e outros curiosos que queiram adquirir conhecimentos na área de desenvolvimento de software. Nosso objetivo é que este livro os ajude na fascinante empreitada de aprender a programar de forma elegante e eficaz e que ele permita um bom início rumo a uma formação sólida em programação que é uma condição fundamental que os desafios da informática do século XXI nos impõem. Abraços e boa jornada! São Paulo, março de 2006. Alfredo Goldman, Fabio Kon e Paulo J. S. Silva xiii xiv PREFÁCIO Capítulo 1 Teatro de Objetos Vamos iniciar a nossa jornada ao fascinante mundo da orientação a objetos de forma dramática: com um Teatro de Objetos. Se você está usando este livro em um curso, reserve juntamente com seu professor uma parte da primeira aula para realizar a encenação descrita neste capítulo. Se você trabalha em uma empresa, reúna-se com colegas de trabalho ou com amigos interessados em programação para exercitar suas qualidades dramáticas. Liberte o artista que existe dentro de você!’ O objetivo do Teatro de Objetos é fazer com que os alunos vivenciem um jogo interativo do qual participam vários “objetos” realizando diferentes formas de ações e comunicações. Os conceitos de orientação a objetos empregados no teatro não são explicitamente explicados já no primeiro capítulo mas serão abordados ao longo do livro. Em um curso de Introdução á Ciência da Computação, normalmente a primeira metade da primeira aula é dedicada a uma conversa informal com os alunos explicando quais são os objetivos da disciplina (e do curso inteiro, se for o caso). É sempre interessante também conversar sobre contatos prévios que os alunos tiveram com informática e com programação. É bom deixar claro que este livro pode ser acompanhado por uma pessoa que nunca viu um computador na frente em sua vida, mas que aprender a programar não é uma tarefa fácil, é preciso se empenhar. Na segunda metade da aula, exercitamos as habilidades dramáticas: para ilustrar o funcionamento de um programa de computador complexo, vamos fazer de conta que somos partes de um programa de computador trabalhando em conjunto para atingir um certo objetivo. Se você estiver organizando a encenação com seus colegas, você pode fazer um certo suspense sobre qual é o objetivo (simular uma disputa de pênaltis) e sobre como ele será alcançado. 1.1 Disputa de pênaltis A “peça” que encenaremos representará uma disputa de pênaltis entre dois times e contará com a participa- ção de cerca de 26 atores desempenhando 8 papéis. Se você não tiver 26 atores disponíveis, você pode elaborar a sua própria adaptação da peça. Os papéis são: • Técnico (2 atores) • Juiz (1 ator) • Bandeirinha (2 atores) • Gandula (1 ator) 1 4 CAPÍTULO 1. TEATRO DE OBJETOS 4. Torcedor Mal-Educado • Cartão de Identificação – Nome do Papel: Torcedor Mal-Educado – Mensagens que entende: Ação, VenceuOTimeX – Atributos: Time: , Camisa número: 12 • Comportamento – mensagem: Ação⇒ ação: assista ao jogo emitindo opiniões duvidosas sobre o andamento da peleja e manifestando a sua raiva ou alegria pelo desenrolar do jogo. – mensagem: VenceuOTimeX⇒ ação: se TimeX é igual ao atributo Time no seu cartão de identi- ficação, xingue o adversário. Caso contrário, xingue o adversário desesperadamente (mas, por favor, não se esqueça que estamos em uma universidade). 5. Juiz • Cartão de Identificação – Nome do Papel: Juiz – Mensagens que entende: Ação, Irregularidade • Comportamento – mensagem: Ação⇒ ação: coordene o andamento da disputa de pênaltis enviando mensagens SuaVez para o técnico do time batedor e para o goleiro defensor a cada nova batida. Quando os personagens estiverem a postos, emita a mensagem CobrançaAutorizada. Faça a contagem de gols e quando houver um vencedor, emita a mensagem VenceuOTimeX onde TimeX é o nome do time vencedor. A disputa de pênaltis é feita alternadamente, 5 cobranças para cada time. Se não houver um ganhador após as 5 cobranças, são feitas novas cobranças alternadamente até que haja um vencedor. – mensagem: Irregularidade⇒ ação: se a mensagem foi enviada por um Bandeirinha, ignore a cobrança recém-efetuada e ordene que ela seja realizada novamente enviando a mensagem RepitaCobrança ao técnico apropriado. 6. Gandula • Cartão de Identificação – Nome do Papel: Gandula – Mensagens que entende: CobrançaAutorizada • Comportamento – mensagem: CobrançaAutorizada ⇒ ação: preste atenção à cobrança do pênalti. Após a conclusão da cobrança, pegue a bola e leve-a de volta à marca de pênalti. 1.1. DISPUTA DE PÊNALTIS 5 7. Técnico • Cartão de Identificação – Nome do Papel: Técnico – Mensagens que entende: SuaVez, RepitaCobrança, VenceuOTimeX – Atributos: Time: • Comportamento – mensagem: SuaVez⇒ ação: escolha um dos seus jogadores para efetuar a cobrança e envie a mensagem SuaVez. Não repita jogadores nas 5 cobranças iniciais. – mensagem: RepitaCobrança⇒ ação: envie a mensagem SuaVez para o jogador que acabou de efetuar a cobrança. – mensagem: VenceuOTimeX⇒ ação: se TimeX é igual ao atributo Time no seu cartão de iden- tificação, comemore; caso contrário, diga que o seu time foi prejudicado pela arbitragem e que futebol é uma caixinha de surpresas. 8. Bandeirinha • Cartão de Identificação – Nome do Papel: Bandeirinha – Mensagens que entende: Cobrança Autorizada, VenceuOTimeX • Comportamento – mensagem: CobrançaAutorizada⇒ ação: verifique se o goleiro realmente não avança antes de o batedor chutar a bola. Caso ele avance, envie uma mensagem Irregularidade para o Juiz. – mensagem: VenceuOTimeX⇒ ação: se TimeX não é o nome do time da casa, distancie-se da torcida pois você acaba de se tornar um alvo em potencial. 6 CAPÍTULO 1. TEATRO DE OBJETOS 2.1. HISTÓRIA DA COMPUTAÇÃO E ARQUITETURA DO COMPUTADOR 9 • Avanços nas calculadoras de mesa⇒ Em 1890, as máquinas permitiam: – acumular resultados parciais – armazenamento e reentrada automática de resultados passados (memória) – imprimir resultados em papel • MARK 1, criada em 1937 por Howard Aiken, professor de Matemática Aplicada de Harvard – calculadora eletromecânica com motor elétrico – pesava 5 toneladas, usava toneladas de gelo para refrigeração – multiplicava dois números de 23 dígitos em 3 segundos • John Vincent Atanasoff, Universidade Estadual de Iowa – construiu o que é considerado o primeiro computador digital entre 1937 e 1942 – calculadora com válvulas a vácuo (240 válvulas) – resolvia equações lineares, diferenciais e de balística – manipulava números binários • Rumo à programabilidade • Alan Turing, – Trabalhou para o exército inglês ajudando a quebrar o código criptográfico da máquina Enigma criada pelos alemães – Realizou importantes contribuições práticas e teóricas à Ciência da Computação – 1912: nasce em Londres – 1935: Ganha bolsa para realizar pesquisas no King’s College, Cambridge – 1936: Elabora “Máquina de Turing”, pesquisas em computabilidade – 1936-38: Princeton University. Ph.D. Lógica, Álgebra, Teoria dos Números – 1938-39: Cambridge. É apresentado à máquina Enigma dos alemães – 1939-40: “The Bombe”, máquina para decodificação do Enigma criada em Bletchley Park – 1939-42: “quebra” Enigma do U-boat, aliados vencem batalha do Atlântico – 1943-45: Consultor-chefe anglo-americano para criptologia – 1947-48: Programação, redes neurais e inteligência artificial – 1948: Manchester University – 1949: Pesquisas sobre usos do computador em cálculos matemáticos avançados – 1950: Propõe “Teste de Turing” para inteligência de máquinas – 1952: Preso por homossexualidade, perde privilégios militares – 1953-54: Trabalho não finalizado em Biologia e Física; tem sua reputação e vida destruídas pelos militares ingleses 10 CAPÍTULO 2. HISTÓRIA DA COMPUTAÇÃO Figura 2.1: Arquitetura do ENIAC – 1954: Suicida-se em Wilmslow, Cheshire – Livro interessante sobre sua vida e obra: Alan Turing: the Enigma de Andrew Hodges, 2000 – Sítio sobre a vida de Turing mantido pelo autor deste livro: http://www.turing.org.uk/turing • ENIAC (Electronic Numerical Integrator and Computer), 1945 – por alguns, considerado o primeiro computador eletrônico – números de 10 dígitos decimais – 300 multiplicações ou 5000 somas por segundo – 17486 válvulas, a queima de válvulas era quase que diária – 6000 comutadores manuais e centenas de cabos usados na programação – programação era muito difícil • Arquitetura do ENIAC (ver Figura 2.1) – programa especificado manualmente em "hardware" com conexões semelhantes àquelas que as velhas telefonistas utilizavam – memória de dados separada do controle e separada do programa – o controle é formado por circuitos eletroeletrônicos • John Von Neumann, matemático, 1945 – estudo abstrato de modelos de computação levou à arquitetura do computador moderno – o programa deve ser guardado no mesmo lugar que os dados: na memória – Arquitetura de Von Neumann (ver Figura 2.2) – hoje em dia, há vários tipos de memória ROM, RAM, flash RAM, etc.) – o controlador em memória, levou à idéia de sistema operacional que temos hoje – Nunca diga nunca... 2.1. HISTÓRIA DA COMPUTAÇÃO E ARQUITETURA DO COMPUTADOR 11 Figura 2.2: Arquitetura de Von Neumann ∗ Aiken declarou em 1947 que nunca haveria necessidade de mais de um ou dois computadores programáveis e que os projetos neste sentido deveriam ser abandonados ∗ Bill Gates declarou na década de 1980 que a Microsoft nunca desenvolveria um sistema ope- racional de 32 bits • Anos 50 – 1953: IBM vende 15 máquinas baseadas no modelo de Neumann – transistores – memória magnética ("magnetic core memory") • Anos 60 – circuitos impressos / circuitos integrados (chips) – crescimento segundo lei de Moore, que diz que o número de transistores em circuitos integrados duplica a cada 18 meses. Esta lei continua valendo até hoje – computação limitada a poucos computadores de grande porte • Anos 70 – indo contra o modelo centralizador da IBM, geração sexo, drogas e rock-and-roll da California exige a democratização da informática – revista esquerdista da Universidade da Califórnia em Berkeley People’s Computer Company de- fende a criação de computadores pessoais e de cooperativas de informação – Steve Jobs cria a Apple em garagem em ~1975 e investe lucros do Apple II em shows de Rock (82) – nasce a Microsoft – governo da Califórnia apóia microinformática 14 CAPÍTULO 2. HISTÓRIA DA COMPUTAÇÃO Capítulo 3 Conversor de Temperaturas Quais novidades veremos neste capítulo? • primeiro programa em Java. 3.1 Analogia entre dramatização da disputa de pênaltis e Programação Ori- entada a Objetos Terminologia Teatral Terminologia de Programação Orientada a Objetos personagem (papel) classe (tipo) ator objeto envio de mensagem envio de mensagem, chamada de método ou chamada de função Na dramatização, podíamos enviar uma mensagem (dizer alguma coisa) para um ator. Na programação orien- tada a objetos, podemos enviar uma mensagem para (ou chamar um método de) um objeto. Os cartões de identificação definem os papéis dos atores e os scripts especificam o comportamento dos atores no decorrer da peça. A linguagem Java permite que especifiquemos a mesma coisa. Um cartão de identificação tem 3 partes, essas mesmas 3 partes aparecem na definição de uma classe em Java. Por exemplo, o bandeirinha em Java seria mais ou menos assim: c l a s s B a n d e i r i n h a { C o b r a n ç a A u t o r i z a d a { / / V e r i f i c a se o g o l e i r o r e a l m e n t e não avança a n t e s de o b a t e d o r . . . } VenceuOTime ( NomeDoTime ) { / / Se NomeDoTime não é o nome do t i m e da casa , d i s t a n c i e −se da t o r c i d a . . . } } 15 16 CAPÍTULO 3. CONVERSOR DE TEMPERATURAS 3.2 Um exemplo real em Java: um conversor de Celsius para Fahrenheit Sempre o primeiro passo antes de programar é analisar o problema. F−32 9 = C 5 ⇒ F−32 = 9 5 C⇒ F = 9 5 C +32 Traduzindo esta fórmula para Java temos F=9*C/5+32. A seguir iremos criar diversas classes para realizar a conversão entre Celsius e Fahrenheit. 1. Primeira tentativa: programa em Java para converter 40 graus Celsius para Fahrenheit. c l a s s Conve r so r { i n t c e l s i u s P a r a F a h r e n h e i t ( ) { re turn 9 ∗ 40 / 5 + 3 2 ; } } • para executar este conversor dentro do DrJava1, podemos digitar o seguinte na janela do interpreta- dor (chamada de interactions): Conve r so r c1 = new Conve r so r ( ) ; c1 . c e l s i u s P a r a F a h r e n h e i t ( ) o DrJava imprimirá o valor devolvido pelo método celsiusParaFahrenheit do objeto c1. • limitação: sempre converte a mesma temperatura. 2. Segunda tentativa: conversor genérico de temperaturas Celsius -> Fahrenheit. É capaz de converter qualquer temperatura de Fahrenheit para Celsius. c l a s s Conver so r2 { i n t c e l s i u s P a r a F a h r e n h e i t ( i n t c ) { re turn 9 ∗ c / 5 + 3 2 ; } } • para executar este conversor, podemos digitar o seguinte na janela do interpretador: Conver so r2 c2 = new Conver so r2 ( ) ; c2 . c e l s i u s P a r a F a h r e n h e i t ( 1 0 0 ) o DrJava imprimirá o valor devolvido pelo método celsiusParaFahrenheit do objeto c2. 1Para mais informações sobre o DrJava consulte o Apêndice A. Capítulo 4 Testes Automatizados Quais novidades veremos neste capítulo? • comando if e else; • comparações == (igualdade) e != (diferença); • definição de variáveis inteiras e de ponto flutuante; • impressão de texto; • comentários. Desde o início, a computação 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 fonógrafo de Thomas Edison em 1889). Várias outras histórias reais, ou nem tanto, também apareceram no início da informática. Infelizmente, é muito difícil garantir que não existam erros em programas. Uma das formas de se garantir que certos erros não vão ocorrer é testando algumas situações. Apesar da célebre afirmação de Edsger Dijkstra 1 de que testes podem apenas mostrar a presença de erros e não a sua ausência, eles podem ser os nossos grandes aliados no desenvolvimento de programas corretos. Intui- tivamente, quanto mais testes fizermos em um programa e quanto mais abrangentes eles forem, mais confiantes podemos ficar com relação ao seu funcionamento. Por outro lado, podemos usar o próprio computador para nos ajudar, isto é, podemos criar testes automatizados. Em vez de fazermos os testes “na mão”, faremos com que o computador seja capaz de verificar o funcionamento de uma seqüência de testes. Veremos neste capítulo como desenvolver testes automatizados, passo a passo, para os conversores de temperatura vistos anteriormente. No início da computação não havia uma preocupação muito grande com os testes, que eram feitos de forma manual pelos próprios programadores. Os grandes testadores eram os usuários finais. É interessante notar que isto acontece com alguns produtos ainda hoje. Com o aparecimento da Engenharia de Software ficou clara a necessidade de se efetuarem testes, tanto que em várias empresas de desenvolvimento de software existe a figura do testador, responsável por tentar encontrar erros em sistemas. Hoje existe uma tendência para se 1Um dos mais influentes membros da geração dos criadores da Ciência da Computação. A página http://www.cs.utexas.edu/ users/EWD contém cópias de vários de seus manuscritos. 19 20 CAPÍTULO 4. TESTES AUTOMATIZADOS considerar que testes automatizados são muito importantes, devendo ser escritos mesmo antes de se escrever o código propriamente dito, técnica esta chamada de testes a priori. Veremos como testar os diversos conversores de temperatura. Como testar o nosso primeiro programa em Java (Conversor). Conve r so r c1 = new Conve r so 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 ( ) == 104) System . o u t . p r i n t l n ( " Func iona " ) ; e l s e System . o u t . p r i n t l n ( " Não f u n c i o n a " ) ; Note que para fazer o teste utilizamos o comando condicional if else. O formato genérico deste comando é o seguinte. i f (CONDIÇÃO) COMANDO_1; e l s e COMANDO_2; Se a CONDIÇÃO é verdadeira, o COMANDO_1 é executado, caso contrário, o COMANDO_2 é executado. A classe Conversor2 possui um método que aceita um parâmetro, veja o teste abaixo: Conver so r2 c2 = new Conver so r2 ( ) ; / / c r i a duas v a r i á v e i s i n t e i r a s i n t e n t r a d a = 4 0 ; i n t r e s p o s t a E s p e r a d 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 à 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 E s p e r a d a ) System . o u t . p r i n t l n ( " Func iona " ) ; e l s e System . o u t . p r i n t l n ( " Não f u n c i o n a " ) ; Note que, para realizar o teste acima, definimos duas variáveis inteiras chamadas de entrada e respostaEsperada. A linha i n t e n t r a d a = 4 0 ; faz na verdade duas coisas. Primeiro, ela declara a criação de uma nova variável (int entrada;) e, depois, atribui um valor inicial a esta variável (entrada = 40;). Na linguagem Java, se o valor inicial de uma variável não é atribuído, o sistema atribui o valor 0 à variável automaticamente. Note que isso não é necessariamente verdade em outras linguagens como, por exemplo, C e C++. Podemos também 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 as v a r i á v e i s j á foram d e c l a r a d a s acima , b a s t a usá−l a s r e s p o s t a E s p e r a d a = 6 8 ; 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 E s p e r a d a ) System . o u t . p r i n t l n ( " Func iona " ) ; e l s e 21 System . o u t . p r i n t l n ( " Não f u n c i o n a " ) ; e n t r a d a = 100 ; r e s p o s t a E s p e r a d 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 E s p e r a d a ) System . o u t . p r i n t l n ( " Func iona " ) ; e l s e System . o u t . p r i n t l n ( " Não f u n c i o n a " ) ; No programa acima o texto Funciona será impresso na tela a cada sucesso, o que poderá causar uma poluição visual caso tenhamos dezenas ou centenas de testes. O ideal para um testador é que ele fique silencioso caso os testes dêem certo e chame a atenção caso ocorra algum erro. Podemos então mudar o programa para: Conver so r2 c2 = new Conver so r2 ( ) ; i n t e n t r a d a = 4 0 ; i n t r e s p o s t a E s p e r a d 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 E s p e r a d a ) System . o u t . p r i n t l n ( " Não f u n c i o n a p a r a 40 " ) ; e n t r a d a = 2 0 ; r e s p o s t a E s p e r a d a = 6 8 ; 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 E s p e r a d a ) System . o u t . p r i n t l n ( " Não f u n c i o n a p a r a 20 " ) ; e n t r a d a = 100 ; r e s p o s t a E s p e r a d 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 E s p e r a d a ) System . o u t . p r i n t l n ( " Não 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 dos t e s t e s " ) ; Note que o comando if acima foi utilizado sem a parte do else, o que é perfeitamente possível. Adicio- namos também uma linha final para informar o término dos testes. Ela é importante no caso em que todos os testes dão certo para que o usuário saiba que a execução dos testes foi encerrada. Uma forma de simplificar os comandos de impressão é usar a própria entrada como parâmetro, o que pode ser feito da seguinte forma: System . o u t . p r i n t l n ( " Não 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 métodos. Introduziremos um testador automático criando uma classe com apenas um método que faz o que vimos. c l a s s T e s t a C o n v e r s o r 4 { i n t t e s t a T u d o ( ) { Conver so r4 c4 = new Conver so r4 ( ) ; double c e l s i u s = 1 0 . 0 ; double f a h r e n h e i t = 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 ( c e l s i u s ) != f a h r e n h e i t ) System . o u t . p r i n t l n ( "C−> F não f u n c i o n a p a r a " + c e l s i u s ) ; 24 CAPÍTULO 4. TESTES AUTOMATIZADOS Conver so r4 c = new Conver so r4 ( ) ; i f ( c . 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 E s p e r a d a ) System . o u t . p r i n t l n ( " f u n c i o n o u c o n v e r s ã o de " + e n t r a d a + "C p a r a " + r e s p o s t a E s p e r a d a + "F" ) ; e l s e System . o u t . p r i n t l n ( " não f u n c i o n o u c o n v e r s ã o de " + e n t r a d a + "C p a r a " + r e s p o s t a E s p e r a d a + "F" ) ; } void t e s t a C e l s i u s P a r a F a h r e n h e i t ( ) { t e s t e P o n t u a l C p a r a F ( 1 0 . 0 , 5 0 . 0 ) ; t e s t e P o n t u a l C p a r a F ( 2 0 . 0 , 6 8 . 0 ) ; t e s t e P o n t u a l C p a r a F (−40.0 , −40 .0 ) ; t e s t e P o n t u a l C p a r a F ( 1 0 1 . 0 , 2 1 3 . 8 ) ; } void t e s t e P o n t u a l F p a r a C ( double e n t r a d a , double r e s p o s t a E s p e r a d a ) { Conver so r4 c = new Conver so r4 ( ) ; i f ( c . f a h r e n h e i t P a r a C e l s i u s ( e n t r a d a ) == r e s p o s t a E s p e r a d a ) System . o u t . p r i n t l n ( " f u n c i o n o u c o n v e r s ã o de " + e n t r a d a + "F p a r a " + r e s p o s t a E s p e r a d a + "C" ) ; e l s e System . o u t . p r i n t l n ( " não f u n c i o n o u c o n v e r s ã o de " + e n t r a d a + "F p a r a " + r e s p o s t a E s p e r a d a + "C" ) ; } void t e s t a F a h r e n h e i t P a r a C e l s i u s ( ) { t e s t e P o n t u a l F p a r a C ( 5 0 . 0 , 1 0 . 0 ) ; t e s t e P o n t u a l F p a r a C ( 6 8 . 0 , 2 0 . 0 ) ; t e s t e P o n t u a l F p a r a C (−40.0 , −40 .0 ) ; t e s t e P o n t u a l F p a r a C ( 2 1 3 . 8 , 1 0 1 . 0 ) ; } } • Exercício 3 c l a s s T e s t e C o n t a s { i n t t e s t e ( ) { Contas c o n t a s = new Contas ( ) ; double v a l o r = 4 . 0 ; i f ( c o n t a s . c a l c u l a Q u a d r a d o ( v a l o r ) != 1 6 . 0 ) System . o u t . p r i n t l n ( " Não f u n c i o n a p a r a c a l c u l a r o quadrado de 4 " ) ; i f ( c o n t a s . c a l c u l a C u b o ( v a l o r ) != 6 4 . 0 ) System . o u t . p r i n t l n ( " Não f u n c i o n a p a r a c a l c u l a r 4 ao cubo " ) ; re turn 0 ; } } Capítulo 5 Métodos com Vários Parâmetros Quais novidades veremos neste capítulo? • Métodos com vários parâmetros; • Atributos; • Métodos que devolvem nada (void); • Escolha de bons nomes. No último capítulo, vimos um método que recebe vários parâmetros. Apesar de não estarmos apresentando nenhuma novidade conceitual, vamos reforçar a possibilidade da passagem de mais de um parâmetro. Ao chamarmos um método que recebe múltiplos parâmetros, assim como no caso de métodos de um pa- râmetro, devemos passar valores do mesmo tipo que aqueles que o método está esperando. Por exemplo, se um objeto (ator) tem um método (entende uma mensagem) que tem como parâmetro um número inteiro, não podemos enviar a este objeto um número double. Apesar de ser intuitivo, também vale ressaltar que a ordem dos parâmetros é importante, de modo que na chamada de um método devemos respeitar a ordem que está na sua definição. Vamos começar com o cálculo da área de uma circunferência, onde é necessário apenas um parâmetro, o raio: c l a s s C í r c u l o 1 { double c a l c u l a Á r e a ( double r a i o ) { re turn 3 .14159 ∗ r a i o ∗ r a i o ; } } 25 26 CAPÍTULO 5. MÉTODOS COM VÁRIOS PARÂMETROS Nota Lingüística: Em Java, o nome de variáveis, classes e métodos pode conter ca- racteres acentuados. Muitos programadores evitam o uso de acentuação mesmo ao usar nomes em português. Este costume advém de outras linguagens mais antigas, como C, que não permitem o uso de caracteres acentuados. Você pode usar caracteres acentuados se quiser mas lembre-se que, se você tiver uma variável 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 também o perímetro, com o seguinte método: double c a l c u l a P e r í m e t r o ( double r a i o ) { re turn 3 .14159 ∗ 2 . 0 ∗ r a i o ; } O seguinte trecho de código calcula e imprime a área e o perímetro de uma circunferência 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 Retângulo que define métodos para o cálculo do perímetro e da área de um retângulo. Neste caso são necessários dois parâmetros. c l a s s R e t â n g u l o 1 { i n t c a l c u l a Á r e a ( i n t l ado1 , i n t l a d o 2 ) { re turn l a d o 1 ∗ l a d o 2 ; } i n t c a l c u l a P e r í m e t r o ( i n t l ado1 , i n t l a d o 2 ) { re turn 2 ∗ ( l a d o 1 + l a d o 2 ) ; } } As chamadas para os métodos 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 ) ) ; 5.1 Atributos Assim como no exemplo do teatrinho dos objetos onde os jogadores tinham como característica o time e o número da camisa (atributos), também podemos ter algo semelhante para o caso dos retângulos. Podemos fazer com que os dados sobre os lados sejam características dos objetos. Isto é feito da seguinte forma: 5.2. A IMPORTÂNCIA DA ESCOLHA DE BONS NOMES 29 5.2 A importância da escolha de bons nomes A característica mais importante em um programa de computador é a clareza do seu código. Quanto mais fácil for para um programa ser entendido por um ser humano que o leia, melhor será o código. Portanto, é fundamental que os nomes das variáveis, classes e métodos sejam escolhidos com muito cuidado e critério. Programadores inexperientes (e alguns não tão inexperientes assim mas descuidados) tendem a não dar impor- tância a este ponto que é essencial para o desenvolvimento de software de boa qualidade. Os nomes das variáveis devem indicar claramente o seu significado, isto é, devem explicar o que é o conteúdo que elas guardam. Por exemplo, na classe Círculo1 descrita no início deste capítulo, a escolha do nome raio para a variável é perfeita porque ela não deixa a menor dúvida sobre o que a variável irá guardar. Se ao invés de raio, o programador tivesse escolhido x como nome da variável, isto seria péssimo pois o nome x não traria informação nenhuma para o leitor do programa sobre o seu significado. Se o programador tivesse dado o nome r para a variável, a escolha não chegaria a ser péssima, pois o r traz alguma informação, mesmo que sutil. Mas, mesmo assim, não seria uma solução tão boa quanto nomear como raio, pois este não deixa a menor dúvida. Portanto, é importante não ter preguiça de pensar em bons nomes e de escrever nomes um pouco mais longos. Por exemplo, o nome númeroDeAlunos é muito melhor do que nda e melhor do que numAlun. Quanto menor o esforço mental do leitor para compreender o programa, maior serão os ganhos a médio e longo prazos. A economia de alguns segundos que obtemos com o uso de nomes abreviados pode facilmente se tornar em horas de dor de cabeça no futuro. A escolha dos nomes de classes e métodos também deve ser feita criteriosamente. Normalmente as classes representam tipos de objetos do mundo real ou do mundo virtual que estamos criando dentro do computador. Portanto, o mais comum é usarmos substantivos como nome para classes (embora esta não seja uma regra obrigatória). Os nomes das classes tem que explicar muito bem qual o tipo de objeto que ela irá representar. Por exemplo, chamar uma classe de Aluno e depois usar objetos desta classe para guardar as notas de um aluno e calcular sua média, não é uma boa escolha. Provavelmente, neste caso, NotasDeAluno seria um nome melhor. Os métodos representam ações que são realizadas, normalmente manipulando os atributos da classe. Por- tanto, normalmente utiliza-se verbos no imperativo para nomear os métodos (novamente, esta não é uma regra obrigatória). Por exemplo, os métodos calculaÁrea, calculaPerímetro, carregaLados e testaTudo aten- dem bem a este critério. Portanto, antes de escrever sua próxima classe, método ou variável, não se esqueça: nomes são importan- tes! Exercícios 1. Neste exercício, construiremos uma classe que calcula a média aritmética de 4 notas e diz se o dono das notas foi aprovado, está de recuperação 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 30 CAPÍTULO 5. MÉTODOS COM VÁRIOS PARÂMETROS • Saída: Média: 8.15 -> aprovado. Média: 4.3 -> recuperação. Média: 2.9 -> reprovado. Para isso, crie uma classe Aluno com métodos que carreguem as 4 notas em variáveis p1, p2, p3, p4 e um método responsável por calcular a média aritmética das notas e dar o “veredito”. 2. Escreva uma classe Olá com um único método cumprimenta que, a cada chamada, cumprimenta o usuário 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. 3. Construa a classe Inteiro que representa um número inteiro. Essa classe deve ter os seguintes atributos e métodos: Classe Inteiro – Atributos: ∗ int valor Valor do inteiro representado. – Métodos para interação com o usuário 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. Sugestão: imprima o seu 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(); 5.2. A IMPORTÂNCIA DA ESCOLHA DE BONS NOMES 31 Valor: -473158. 4. Acrescente à classe Inteiro algumas operações matemáticas, implementando os seguintes métodos: Classe Inteiro – Mais métodos para interação com o usuário da classe: ∗ int soma(int v) Soma v ao valor deste objeto (valor + v). Este objeto passa a representar o novo valor, que também deve ser devolvido pelo método. ∗ int subtrai(int v) Subtrai v do valor deste objeto (valor - v). Este objeto passa a representar o novo valor, que também deve ser devolvido pelo método. ∗ int multiplicaPor(int v) Multiplica o valor deste objeto por v (valor * v). Este objeto passa a representar o novo valor, que também deve ser devolvido pelo método. ∗ int dividePor(int divisor) Verifica se divisor é diferente de zero. Se não, imprime uma mensagem de erro e não faz nada (devolve o valor inalterado). Se for, divide o valor deste objeto por v (valor / divisor, divisão inteira). Este objeto passa a representar o novo valor, que também deve ser devolvido pelo método. Exemplo de uso no DrJava: > Inteiro i = new Inteiro(); > i.carregaValor(15); > i.subtrai(20) -5 > i.devolveValor() -5 Se quiser, você também pode fazer versões desses métodos que não alteram o valor representado, apenas devolvem o valor da conta. 5. Crie uma classe TestaInteiro que verifica o funcionamento correto da classe Inteiro em diversas situações. Lembre-se de verificar casos como a divisão por diversos valores. Ao escrever os testes, você notará que a classe Inteiro tem uma limitação importante no método dividePor. 6. Crie uma classe Aluno2 para calcular a média aritmética de 4 notas. Mas no lugar de um método que recebe 4 parâmetros, a classe deve conter 4 métodos recebeNotaX, onde X = 1, 2, 3 ou 4, para receber as notas das provas, de modo que cada método receba apenas uma nota. A classe deve conter ainda um método imprimeMédia que imprime a média final do aluno, dizendo se ele foi aprovado ou repro- vado. Em seguida, escreva uma classe TestaAluno2 que verifica se a classe Aluno2 calcula as médias corretamente. 34 CAPÍTULO 6. IF ELSE ENCAIXADOS 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 . " ) ; } } } O método acima pode ser chamado da seguinte forma: T r i a n g u l o R e t â n g u l o r = new T r i a n g u l o R e t â n g u l o ( ) ; r . s a t i s f a z P i t á g o r a s ( 1 , 1 , 1 ) ; r . s a t i s f a z P i t á g o r a s ( 3 , 4 , 5 ) ; Limitações: 1. mesmo que um if seja verdadeiro, ele executa os outros ifs. Em particular, se tivéssemos um triângulo retângulo para o qual vários desses ifs fossem verdadeiros, ele imprimiria esta mensagem várias vezes (neste exemplo específico, isto não é possível); 2. este método só imprime uma mensagem se os dados correspondem às medidas de um triângulo retângulo, se não é um triângulo retângulo, ele não imprime nada. Através do uso do else podemos resolver estes dois problemas e imprimir mensagens afirmativas e nega- tivas, explicando exatamente o que foi verificado. c l a s s T r i a n g u l o R e t â n g u l o 2 { void s a t i s f a z P i t á g o r a s ( i n t a , i n t b , i n t c ) { i f ( a ∗ b ∗ c != 0) / / nenhum lado pode s e r nu lo { 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 . " ) ; e l s e System . o u t . p r i n t l n ( " Não é 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 ( " Não é t r i â n g u l o p o i s p o s s u i l a d o de comprimento nu lo . " ) ; } } Caso sejam necessários outros métodos, como um para o cálculo de perímetro, é interessante colocar os lados como atributos da classe, ou seja, propriedades dos objetos do tipo TrianguloRetângulo3. c l a s s T r i a n g u l o R e t â n g u l o 3 { i n t 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 ) { 35 a = l 1 ; b = l 2 ; c = l 3 ; } i n t c a l c u l a P e r í m e t r o ( ) { re turn a + b + c ; } void s a t i s f a z P i t á g o r a s ( ) { i f ( a ∗ b ∗ c != 0) / / nenhum lado pode s e r nu lo { 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 . " ) ; e l s e System . o u t . p r i n t l n ( " Não é 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 ( " Não é t r i â n g u l o p o i s p o s s u i l a d o de comprimento nu lo . " ) ; } } Exercícios 1. Você foi contratado por uma agência de viagens para escrever uma classe em Java para calcular a conver- são de reais para dólar de acordo com a taxa de compra e a taxa de venda. Para isso, escreva uma classe ConversorMonetário que inclua, obrigatoriamente, os seguintes métodos: (a) defineTaxaCompra() e defineTaxaVenda(); (b) imprimeTaxas() que imprime o valor das 2 taxas de conversão; (c) vendeDólar() que recebe uma quantia em dólares e devolve o valor correspondente em reais; (d) compraDólar() que recebe uma quantia em dólares e devolve o valor correspondente em reais. Em seguida, escreva uma classe TestaConversorMonetário que define diferentes taxas de compra e venda de dólares e, para cada taxa de conversão, realiza operações de compra e venda. 2. Escreva uma classe Baskara que possui 3 atributos do tipo double correspondentes aos coeficientes a, b e c de uma equação do segundo grau. Escreva um método para carregar valores nestes atributos e, em seguida, escreva os 4 métodos seguintes: (a) delta() deve calcular o δ da fórmula de Baskara; (b) númeroDeRaízesReais() deve devolver um inteiro indicando quantas raízes reais a equação pos- sui; 36 CAPÍTULO 6. IF ELSE ENCAIXADOS (c) imprimeRaízesReais() deve imprimir as raízes reais; (d) imprimeRaízesImaginárias() deve imprimir as raízes imaginárias. Para calcular a raiz quadrada, você pode utilizar o método java.lang.Math.sqrt(double x), que recebe um double como parâmetro e devolve outro double. Você pode supor que o primeiro coeficiente, a, é diferente de 0. 3. Crie uma classe contendo um método que, dado um ponto determinado pelas suas coordenadas x e y, reais, imprime em qual quadrante este ponto está localizado. O primeiro quadrante corresponde aos pontos que possuem x e y positivos, o segundo quadrante a x positivo e y negativo e assim por diante. Para resolver este exercício, será necessário utilizar os operadores < e >. Sua utilização é similar à do operador == utilizado até agora. 4. [Desafio!] São apresentadas a você doze esferas de aparência idêntica. Sabe-se que apenas uma delas é levemente diferente das demais em massa, mas não se sabe qual e nem se a massa é maior ou menor. Sua missão é identificar essa esfera diferente e também dizer se ela é mais ou menos pesada. Para isso você tem apenas uma balança de prato (que só permite determinar igualdades/desigualdades). Ah, sim, pequeno detalhe: o desafio é completar a missão em não mais que três pesagens. Escreva um programa que resolve esse desafio. O seu programa deve dar uma resposta correta sempre e também informar as três ou menos pesagens que permitiram concluir a resposta. Como esse problema é um tanto complicado, recomendamos que você implemente o modelo descrito no quadro a seguir. Cada esfera deve ser representada por um inteiro entre 1 e 12. Para representarmos a esfera diferente, usaremos, além do identificador inteiro, uma variável 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 método resolveDesafioDasDozeEsferas não deve de modo algum acessar os atributos esferaDiferente e maisPesada para inferir a resposta. Quem dá pistas para este método sobre o valor desses atributos são os métodos pesa#x#. Lembre-se de que você também pode implementar métodos adicionais, se achar necessário ou mais elegante. Ou ainda, se você já se sente seguro(a), você pode implementar a(s) sua(s) própria(s) classe(s). Exemplo de uso no DrJava: > DesafioDasEsferas dde = new DesafioDasEsferas(); > dde.defineEsferaDiferente(4, false); Início 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) balança equilibrada. Resposta: esfera 3 mais leve. [Resposta errada!] Capítulo 7 Programas com Vários Objetos Quais novidades veremos neste capítulo? • Programas com vários objetos. Até agora, todos os programas que vimos lidavam com apenas um objeto. No entanto, podemos ter progra- mas que lidam com vários objetos. Estes objetos podem pertencer todos à mesma classe ou a classes diferentes. Exemplo: 1. Vários 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 f l o r D e L a r a n j e i r a = new F l o r ( ) ; r o s a . c o r ( " ve rme lha " ) ; r o s a . aroma ( " mui to a g r a d á v e l " ) ; m a r g a r i d a . aroma ( " s u t i l " ) ; f l o r D e L a r a n j e i r a . aroma ( " d e l i c i o s o " ) ; 2. Vários objetos de tipos (classes) diferentes: Cachor ro f l o q u i n h o = new Cachor ro ( ) ; Gato mingau = new Gato ( ) ; Rato t o p o G i g g i o = new Rato ( ) ; Vaca mimosa = new Vaca ( ) ; f l o q u i n h o . l a t a ( ) ; mingau . mie ( ) ; t o p o G i g g i o . comaQuei jo ( ) ; 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 . passePorCima ( f l o q u i n h o , mingau , t o p o G i g g i o ) ; 39 40 CAPÍTULO 7. PROGRAMAS COM VÁRIOS OBJETOS Vejamos agora um exemplo de utilização de objetos de 3 tipos diferentes em conjunto. Neste exemplo, teremos 3 classes representando prismas, quadrados e triângulos retângulos e criaremos uma instância de quadrado, uma de triângulo retângulo e duas de prismas. Note, no exemplo abaixo, que utilizamos um padrão diferente para nomear os métodos que servem para atribuir valores aos atributos. Segundo este padrão, muito utilizado por programadores avançados em linguagens como C++ e Smalltalk, o nome do método é exatamente o nome do atributo correspondente. Por exemplo, o método void altura(double a) é utilizado para definir o valor do atributo altura e assim por diante. Ao escrever seus programas, você é livre para escolher entre qualquer um dos pa- drões existentes, mas é importante que você seja coerente, ou seja, após escolher o padrão de nomeação, aplique-o consistentemente em todo o seu código. c l a s s Pr i sma { double a l t u r a ; double áreaDaBase ; void a l t u r a ( double a ) { a l t u r a = a ; } void áreaDaBase ( double a ) { áreaDaBase = a ; } double volume ( ) { re turn áreaDaBase ∗ a l t u r a ; } } c l a s s Quadrado { double l a d o ; void l a d o ( double l ) { l a d o = l ; } double á r e a ( ) { re turn l a d o ∗ l a d o ; } } c l a s s T r i a n g u l o R e t â n g u l o { double c a t e t o 1 ; double c a t e t o 2 ; 41 / / n o t e a i n d e n t a ç ã o supercompac ta ! void c a t e t o 1 ( double c ) { c a t e t o 1 = c ; } void c a t e t o 2 ( double c ) { c a t e t o 2 = c ; } double á r e a ( ) { re turn c a t e t o 1 ∗ c a t e t o 2 / 2 . 0 ; } } Agora, utilizando o interpretador, podemos criar objetos destes vários tipos e utilizá-los em conjunto: Quadrado q = new Quadrado ( ) ; T r i a n g u l o R e t â n g u l o t r = new T r i a n g u l o R e t â n g u l o ( ) ; P r i sma pr i smaBaseQuadrada = new Pr i sma ( ) ; P r i sma p r i s m a B a s e T r i a n g u l a r = new Pr i sma ( ) ; q . l a d o ( 1 0 . 0 ) ; t r . c a t e t o 1 ( 2 0 . 0 ) ; t r . c a t e t o 2 ( 3 0 . 0 ) ; p r i smaBaseQuadrada . a l t u r a ( 3 . 0 ) ; p r i s m a B a s e T r i a n g u l a r . a l t u r a ( 1 . 0 ) ; p r i smaBaseQuadrada . á reaDaBase ( q . á r e a ( ) ) ; p r i s m a B a s e T r i a n g u l a r . á reaDaBase ( t r . á r e a ( ) ) ; i f ( p r i smaBaseQuadrada . 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 pr i s ma de base q u a d r a d a tem maior 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 ( ) > pr i smaBaseQuadrada . volume ( ) ) System . o u t . p r i n t l n ( "O pr i s ma de base t r i a n g u l a r tem maior volume " ) ; e l s e System . o u t . p r i n t l n ( "Ambos os p r i s m a s têm 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 em vez de apenas Enter no final de cada linha dos ifs encaixados. Apenas no final da última linha (a que contém o println final) é que se deve digitar apenas Enter para que o DrJava então interprete todas as linhas de uma vez. Exercícios 1. Utilizando a classe Conversor5 definida no exercício 1 do Capítulo 3, escreva uma classe contendo três métodos, onde cada método recebe uma temperatura x utilizando uma escala de temperaturas e imprime os valores de x nas demais escalas de temperatura. 2. Escreva uma classe Rendimentos que contenha os seguintes métodos a fim de contabilizar o total de rendimentos de uma certa pessoa em um certo ano: 44 CAPÍTULO 7. PROGRAMAS COM VÁRIOS OBJETOS Capítulo 8 Laços e Repetições Quais novidades veremos neste capítulo? • A idéia de laços em linguagens de programação; • O laço while; • O operador que calcula o resto da divisão inteira: %; • Números inteiros grandes. 8.1 Laços em linguagens de programação Vamos apresentar para vocês um novo conceito fundamental de programação: o laço. Mas o que pode ser isso? Um nome meio estranho, não? 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 não estão em guerra com ninguém. Você arruma a mala e se prepara para a 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 conversão de temperaturas de Fahrenheit para Celsius. Ela será muito útil, por exemplo, para entender o noticiário e saber o que vestir no dia seguinte. Você então se lembra que já tem um conversor pronto. Basta então usá-lo para montar a tabela. Você chama então o DrJava e começa uma nova sessão interativa. 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) 45 46 CAPÍTULO 8. LAÇOS E REPETIÇÕES -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 método fahrenheitParaCelsius (pois elas confundem) e imprimir a tabela. Será que existe algo de especial nas diversas chamadas do método fahrenheitParaCelsius acima? Todas elas são muito parecidas e é fácil adivinhar a próxima se sabemos qual a passada. Ou seja, a lei de formação das diversas chamadas do método é simples e bem conhecida. Não seria interessante se fosse possível escrever um trecho de código compacto que representasse essa idéia? Para isso servem os laços: eles permitem a descrição de uma seqüência de operações repetitivas. 8.2 O laço while O nosso primeiro laço será o while, a palavra inglesa para enquanto. Ele permite repetir uma seqüência de operações enquanto uma condição se mantiver verdadeira. Mais uma vez, um exemplo é a melhor explicação. Experimente digitar as seguintes linhas de código no painel de interações do DrJava (lembre-se que para di- gitarmos as 5 linhas do comando while abaixo, é necessário usarmos Shift+Enter em vez 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:
Docsity logo



Copyright © 2024 Ladybird Srl - Via Leonardo da Vinci 16, 10126, Torino, Italy - VAT 10816460017 - All rights reserved