Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original
Clique para editar o estilo do título mestre Clique para editar o estilo do subtítulo mestre * * * Implementação de Programas Capítulo 2 – Entendendo as definições de classes. Prof. Ricardo Guedes – CEFETCE Do livro: Programação Orientada a Objetos com Java Uma introdução prática usando o BLUEJ De: David J. Barnes e Michael Kölling Editora PEARSON – Prentice Hall * * * 1. Máquinas de vender bilhetes As estações de trem freqüentemente fornecem máquinas de vender bilhetes que imprimem um bilhete quando um cliente insere a quantia correta para pagar a passagem. Definiremos uma classe (TicketMachine) que modela algo similar a essas máquinas de vender bilhetes. Abra o projeto naive-ticket-machine no BlueJ. * * * 1. Máquinas de vender bilhetes EXERCÍCIO 2.1 Crie um objeto TicketMachine com o preço do bilhete igual a 200. Examine seus métodos. Experimente o método getPrice. Utilize o método insertMoney para simular a inserção de uma quantidade de dinheiro na máquina e depois use getBalance para verificar se a máquina tem o registro da quantidade inserida. Chame o método printTicket. EXERCÍCIO 2.2 Qual valor é retornado se você verificar o saldo da máquina depois que ela imprimiu um bilhete? * * * 1. Máquinas de vender bilhetes EXERCÍCIO 2.3 Experimente inserir quantidades diferentes de dinheiro antes de imprimir bilhetes. Você consegue notar alguma coisa estranha no comportamento da máquina? O que acontece se você insere muito dinheiro na máquina – você recebe algum reembolso? O que acontece se você não inserir o suficiente e depois tentar imprimir um bilhete? * * * 1. Máquinas de vender bilhetes EXERCÍCIO 2.4 Tente entender bem o funcionamento da máquina de vender bilhetes interagindo com ela na bancada de objetos antes de ver como a classe TicketMachine é implementada. EXERCÍCIO 2.5 Crie outra máquina de vender bilhetes com um preço diferente. Compre um bilhete nessa máquina. O bilhete parece diferente? * * * 2. Examinando uma definição de classe Examine o código-fonte da classe TicketMachine dando um clique duplo em seu ícone no diagrama de classes. * * * 3. Campos, construtores e métodos Uma classe tem a seguinte estrutura: public class NomeDaClasse { Campos Construtores Métodos } Os campos armazenam os dados para uso de cada objeto. Os construtores permitem que cada objeto seja configurado adequadamente quando ele é criado. Os métodos implementam o comportamento dos objetos. * * * 3. Campos, construtores e métodos O código fonte da maioria das classes pode ser dividido em duas partes: um pequeno envoltório externo que simplesmente nomeia a classe e uma parte interna, muito maior, que faz todo o trabalho. Nesse caso o envoltório é o seguinte: public class TicketMachine { parte interna da classe omitida. } EXERCÍCIO 2.6 Escreva como você acha que pareceriam as camadas externas das classes Student e LabClass – Não se preocupe com a parte interna. * * * 3. Campos, construtores e métodos EXERCÍCIO 2.7 Examinando o código fonte da classe TicketMachine faça uma lista dos nomes dos seus campos, construtores e métodos. Dica: Há apenas um construtor na classe. EXERCÍCIO 2.8 O que torna o construtor diferente dos métodos da classe? * * * 3.1 Campos Os campos armazenam dados para um objeto utilizar. Os campos também são conhecidos como variáveis de instância. A classe TicketMachine tem três campos: price, balance e total. O campo price armazena o preço de um bilhete. O campo balance armazena a quantidade de dinheiro inserido na máquina por um usuário antes de pedir a impressão do bilhete. O campo total armazena a quantidade total de dinheiro inserido na máquina por todos os usuários desde que o objeto foi criado. * * * 3.1 Campos Os campos da classe TicketMachine: public class TicketMachine { private int price; private int balance; private int total; Construtor e métodos omitidos. } * * * 3.1 Campos As definições indicam que os campos são privados (private) do objeto.No capítulo 5 veremos o que isso significa. Por enquanto sempre definiremos os campos como sendo privados. Todos os três campos são do tipo int. Como os campos podem armazenar valores que podem variar ao longo do tempo, eles também são conhecidos como variáveis de instância. * * * 3.1 Campos - Comentários Cada campo tem sua própria declaração no código-fonte. Na linha acima de cada um adicionamos uma única linha de texto – um comentário – para o benefício de leitores humanos. // The price of a ticket from this machine. private int price; Um comentário de uma única linha é iniciado por duas barras sem espaços entre elas. Os comentários são inseridos no código-fonte de uma classe para fornecer explicações a leitores humanos. Eles não têm nenhum efeito na funcionalidade da classe. * * * 3.1 Campos - Comentários Para introduzir comentários mais detalhados usamos os comentários de múltiplas linhas. Eles começam com o par de caracteres /* e terminam com o par */. /** * TicketMachine models a naive ticket machine that issues * flat-fare tickets. * The price of a ticket is specified via the constructor. * It is a naive machine in the sense that it trusts its users * to insert enough money before trying to print a ticket. * It also assumes that users enter sensible amounts. * * @author David J. Barnes and Michael Kolling * @version 2002.02.06 */ * * * 3.1 Campos – Diagrama de um objeto * * * 3.2 Construtores Os construtores de uma classe têm o papel especial a cumprir: colocar cada objeto dessa classe, quando ele está sendo criado, em um estado adequado. Isso também é chamado de inicialização. Os campos do objeto são inicializados no construtor. Deve-se fornecer o custo de um bilhete sempre que se cria um novo objeto da classe TicketMachine. Os campos balance e total recebem valores iniciais iguais a zero. * * * 3.2 Construtores – Diagrama de um objeto * * * 3.2 Construtores Em Java, todos os campos são automaticamente inicializados com um valor padrão se não forem explicitamente inicializados. Para campos do tipo int esse valor é 0. Assim sendo, não seria necessário inicializar os campos balance e total com 0. É preferível fazer as inicializações explícitas. Não há nenhuma desvantagem nisso e funciona bem para documentar o que realmente está acontecendo. * * * 4. Transmitindo dados via parâmetros Construtores e métodos recebem valores via parâmetros. Os parâmetros são definidos no cabeçalho do construtor ou do método. public TicketMachine(int ticketCost) Esse construtor tem um único parâmetro, ticketCost, que é do tipo int – o mesmo tipo que tem o campo price. * * * 4. Transmitindo dados via parâmetros * * * 4. Transmitindo dados via parâmetros Distinguimos entre nomes dos parâmetros dentro de um construtor ou método dos valores passados de fora, referindo-nos aos nome como parâmetros formais e aos valores como parâmetros reais. Portanto, ticketCost é um parâmetro formal e o valor fornecido pelo usuário, no caso 200, é o parâmetro real. Como são capazes de armazenar valores, os parâmetros formais são outro tipo de variável. Nos diagramas, todas as variáveis são represen-tadas por caixas brancas. * * * 4. Escopo de uma variável Um parâmetro formal está disponível para um objeto apenas dentro do corpo de um construtor ou método que o declara. O escopo de uma variável define a parte do código fonte onde a variável pode ser acessada. O escopo de um campo é toda a classe – ele pode ser acessado a partir de qualquer lugar da classe. * * * 4. Tempo de vida de uma variável O tempo de vida de um parâmetro está limitado pelo tempo de execução de um método ou construtor. Quando o construtor tiver finalizado a execução, todo o espaço do construtor é removido junto com as variáveis de parâmetros mantidas dentro dele. O tempo de vida de um campo é o mesmo que o tempo de vida do objeto a que ele pertence. * * * 5. Instruções de atribuição As instruções de atribuição armazenam o valor representado pelo lado direito da instrução na variável identificada à esquerda. <nomeDaVariável> = <valor>; Por exemplo, o corpo do construtor contém a seguinte instrução de atribuição: price = ticketCost; O operador de atribuição é o sinal de igualdade ‘=‘. O lado direito é chamado expressão: expressões são elementos que calculam valores. Uma regra sobre instruções de atribuição é que o tipo calculado pela expressão deve corresponder ao tipo da variável à qual é atribuído o valor da expressão. Essa mesma regra também se aplica entre os parâmetros formais e os parâmetros reais: O tipo de uma expressão de parâmetro real deve corresponder ao tipo da variável de parâmetro formal. * * * 6. Métodos Os métodos têm duas partes: um cabeçalho e um corpo. public class TicketMachine { Campos omitidos Construtor omitido /** * Return the price of a ticket. */ public int getPrice() { return price; } } As três primeiras linhas são um comentário que descreve o que o método faz. * * * 6. Métodos A quarta linha é o cabeçalho ou assinatura do método. É importante distinguir entre assinaturas de método e declarações de campos. Podemos dizer que getPrice é um método e não um campo porque é seguido por um par de parênteses. O corpo do método é o restante do método depois do cabeçalho. Ele é sempre circundado por um par de chaves: ‘{‘ e ‘}’. O corpo dos métodos contém declarações e instruções que definem o que acontece dentro de um objeto quando esse método é chamado. * * * 6. Métodos Qualquer conjunto de declarações e instruções entre um par de chaves é chamado de bloco. O corpo da classe TicketMachine e os corpos de todos os métodos dentro da classe são blocos. Há uma diferença entre as assinaturas de um construtor e um método: O método tem um tipo de retorno e o construtor não. O nome do construtor deve ser idêntico ao nome da classe e o método pode ter qualquer nome. Tanto construtores como métodos podem ter qualquer número de parâmetros formais, inclusive nenhum. * * * 6. Métodos No corpo do método getPrice há uma única instrução: return price; Essa é uma instrução de retorno. O valor retornado deve ser do mesmo tipo declarado no cabeçalho do método. Podemos pensar em uma chamada de método como uma pergunta que fazemos a um objeto e no valor de retorno como sendo a resposta do objeto a essa pergunta. * * * 6. Métodos de acesso O método getPrice é um método de acesso. Os métodos de acesso retornam informações sobre o estado de um objeto. Os métodos de acesso são também chamados de métodos get pois é uma prática de programação iniciar os nomes desses métodos com a palavra get. Por exemplo, os métodos getPrice e getBalance. Um método de acesso normalmente contém uma instrução de retorno, para transmitir de volta o valor solicitado. Um método que imprime as informações sobre o estado de um objeto também pode ser classificado como método de acesso. * * * 6. Métodos - Exercícios EXERCÍCIO 2.9 Compare o método getBalance com o método getPrice. Quais são as diferenças entre eles. EXERCÍCIO 2.10 Se uma chamada para getPrice puder ser caracterizada como fazer a pergunta ‘Quanto custa o bilhete?’, como você caracterizaria uma chamada getBalance? EXERCÍCIO 2.11 Se o nome de getBalance for alterado para getAmount, a instrução de retorno precisará ser alterada? * * * 6. Métodos - Exercícios EXERCÍCIO 2.12 Defina um método de acesso, getTotal, que retorne o valor do campo total. EXERCÍCIO 2.13 Tente remover a instrução de retorno do corpo de getPrice. Que mensagem de erro você vê quando tenta compilar a classe? EXERCÍCIO 2.14 Compare as assinaturas de método de getPrice e printTicket. Além de seus nomes, qual é a principal diferença entre elas. EXERCÍCIO 2.15 Os métodos insertMoney e printTicket têm instruções de retorno? O que você acha que isso significa? Você nota alguma coisa nos seus cabeçalhos que possa sugerir por que eles não requerem instruções de retorno? * * * 7. Métodos modificadores Os métodos modificadores alteram o estado de um objeto. Os métodos insertMoney e printTicket são métodos modificadores. EXERCÍCIO 2.16 Crie uma máquina de vender bilhetes com um preço de bilhete de sua escolha. Antes de fazer qualquer outra coisa, chame o método getBalance nele. Agora chame o método insertMoney e forneça-lhe uma quantidade positiva diferente de zero de dinheiro como parâmetro real. Agora chame getBalance novamente. As duas chamadas para o método getBalance mostram saídas diferentes porque a chamada do método insertMoney alterou o estado da máquina de bilhetes modificando o valor do seu campo balance. * * * 7. Métodos modificadores A assinatura de insertMoney tem um tipo de retorno void e um único parâmetro formal, amount, de tipo int. /** * Receive an amount of money in cents from a customer. */ public void insertMoney(int amount) { balance += amount; } Um tipo de retorno void significa que o método não retorna nenhum valor para seu chamador. Nesse caso nenhum diálogo de valor de retorno é mostrado. Em um método que retorna void não há nenhuma instrução de retorno. * * * 7. Métodos modificadores Na instrução balance += amount; O operador += é uma abreviação de: balance = balance + amount; EXERCÍCIO 2.17 Crie uma máquina de vender bilhetes e chame seu método insertMoney. Verifique o saldo com uma chamada ao método getBalance. Agora chame insertMoney e getBalance novamente para verificar se o novo saldo é a soma das duas quantidades passadas para as duas chamadas a insertMoney. EXERCÍCIO 2.18 Agora faça uma pequena alteração no método insertMoney utilizando o editor do BlueJ. Altere o operador ‘+=‘ para ‘=‘. Compile a classe e execute novamente as chamadas de método que foram feitas no exercício anterior. O que o saldo mostra agora? * * * 8. Imprimindo a partir de métodos O método printTicket é o mais complexo da classe TicketMachine. public void printTicket() { // Simulate the printing of a ticket. System.out.println("##################"); System.out.println("# The BlueJ Line"); System.out.println("# Ticket"); System.out.println("# " + price + " cents."); System.out.println("##################"); System.out.println(); // Update the total collected with the balance. total += balance; // Clear the balance. balance = 0; } O método System.out.println imprime seus parâmetros no terminal de texto * * * 8. Imprimindo a partir de métodos - Exercícios EXERCÍCIO 2.19 Adicione um método chamado prompt à classe TicketMachine. Ele deve ter um tipo de retorno void e não aceitar nenhum parâmetro. O corpo do método deve imprimir algo como: Please insert the correct amount of money. EXERCÍCIO 2.20 Adicione um método showPrice à classe TicketMachine. Ele deve ter um tipo de retorno void e não aceitar nenhum parâmetro. O corpo do método deve imprimir algo como: The price of a ticket is xyz cents. Onde xyz deve ser o valor do campo price quando o método é chamado. EXERCÍCIO 2.21 Crie duas máquinas de vender bilhetes como preços de bilhetes diferentes. As chamadas para os métodos showPrice mostram a mesma saída ou saídas diferentes? Como você explica esse efeito? * * * 8. Imprimindo a partir de métodos - Exercícios EXERCÍCIO 2.22 O que você acha que seria impresso se alterasse a quarta instrução de printTicket de modo que price também tivesse aspas ao redor, como segue? System.out.println("# " + "price" + " cents."); EXERCÍCIO 2.23 E sobre a versão seguinte? System.out.println("# price cents."); EXERCÍCIO 2.24 Qualquer uma das duas versões anteriores poderia ser utilizada para mostrar o preço dos bilhetes em máquinas de vender bilhetes diferentes? Explique sua resposta. * * * 9. Resumo da máquina “ingênua” de vender bilhetes. Uma classe tem uma pequena camada externa que dá nome à classe e um corpo interno mais substancial contendo campos, construtores e vários métodos. Os campos são utilizados para armazenar dados que permitem aos objetos manter um estado. Os construtores são utilizados para configurar o estado inicial quando um objeto é criado. Os métodos implementam o comportamento definido para o objeto da classe. Os métodos de acesso fornecem informações sobre o estado de um objeto. Os métodos modificadores alteram o estado de um objeto. * * * 9. Resumo da máquina “ingênua” de vender bilhetes. Construtores são distinguidos de métodos por terem o mesmo nome da classe em que são definidos e por não terem um tipo de retorno. Tanto construtores como métodos podem aceitar parâmetros. Tipos de retorno não-void permitem-nos passar um resultado de um método. Um método com um tipo de retorno não-void terá uma instrução de retorno como a instrução final de seu corpo. * * * 9. Exercícios EXERCÍCIO 2.25 Modifique o construtor de TicketMachine de modo que ele não tenha mais nenhum parâmetro. Em vez disso, o preço de bilhetes deve ser fixado em 1000 centavos. Que efeito isso tem quando você constrói objetos de máquina de vender bilhetes dentro do BlueJ? EXERCÍCIO 2.26 Implemente um método, empty, que simule o efeito de remoção de todo o dinheiro da máquina. Esse método deve ter um tipo de retorno void, e seu corpo simplesmente deve configurar o campo total para zero. Esse método precisa retornar alguns parâmetros? Teste seu método criando um máquina, inserindo algum dinheiro, imprimindo alguns bilhetes, verificando o total e depois esvaziando a máquina. Esse método é um método modificador ou de acesso? * * * 9. Exercícios EXERCÍCIO 2.27 Implemente um método, setPrice, que seja capaz de definir o preço de bilhetes para um novo valor. O novo preço é passado como um valor de parâmetro para o método. Teste seu método criando uma máquina, mostrando o preço de bilhetes, alterando o preço e mostrando o novo preço. Esse método é um método modificador? EXERCÍCIO 2.28 Dê dois construtores à classe. Um deve aceitar um único parâmetro que especifique o preço e o outro não deve aceitar nenhum parâmetro e configurar o preço para ser um valor-padrão de sua escolha. Teste a sua implementação criando máquinas por meio de dois construtores diferentes. * * * 10. Refletindo sobre o projeto da máquina de vender bilhetes. A classe TicketMachine desenvolvida até agora apresenta várias deficiências: Não contém nenhuma verificação que indique que o cliente inseriu dinheiro suficiente para pagar um bilhete. Não reembolsa nenhum valor se o cliente pagar a mais por um bilhete. Não verifica se o cliente insere valores válidos de dinheiro. Experimente inserir um quantidade negativa. Não verifica se o preço de bilhete passado para seu construtor é adequado. O projeto better-ticket-machine é uma tentativa de resolver essas deficiências. * * * 11. Fazendo escolhas: a instrução condicional. Abra o projeto better-ticket-machine. Crie algumas instâncias e veja se você nota qualquer diferença entre essa versão e a versão ingênua anterior. Uma diferença específica é que a nova versão tem um método adicional, refundBalance. Verifique o que acontece quando você o chama. Abra e examine código-fonte da classe TicketMachine. Grande parte dele é semelhante ao projeto naive-ticket-machine. * * * 11. Fazendo escolhas: a instrução condicional. A primeira grande alteração pode ser vista no método getMoney. Agora se utiliza uma instrução condicional para verificar se a quantidade inserida possui um valor maior que zero. Uma instrução condicional permite-nos realizar uma de duas possíveis ações com base no resultado de uma verificação ou teste. Sintaxe ou forma geral da instrução condicional: if (expressão lógica que retorna true ou false) { comandos executados se o resultado for true } else { comandos executados se o resultado for false } * * * 11. Fazendo escolhas: a instrução condicional. O teste utilizado em uma instrução condicional é um exemplo de uma expressão booleana ou expressão lógica. Uma expressão booleana tem apenas dois possíveis resultados: true ou false. Uma instrução condicional utiliza esses dois possíveis valores para escolher entre duas ações. * * * 11. Exercícios EXERCÍCIO 2.29 Verifique se o comportamento que discutimos aqui está correto criando uma instância TicketMachine e chamando insertMoney com diversos valores de parâmetros reais. Verifique o saldo antes e depois de chamar insertMoney. O saldo muda nos casos em que uma mensagem de erro é impressa? Tente prever o que acontece se você inserir o valor zero como parâmetro e então veja se você está certo. EXERCÍCIO 2.30 Preveja o que você acha que acontecerá se você alterar o teste em insertMoney para utilizar o operador maior que ou igual: If (amount >= 0) Verifique suas previsões executando algum teste. Qual a diferença no comportamento do método? EXERCÍCIO 2.31 No projeto shapes, visto no capítulo 1, utilizamos um campo boolean para controlar um recurso dos objetos circle. Qual era esse recurso? Ele era adequado para ser controlado por um tipo com apenas dois valores diferentes? * * * 12. Um exemplo de instrução condicional adicional O método printTicket utiliza, também, uma instrução condicional. Essa instrução verifica se o valor inserido é maior ou igual ao preço de um bilhete. Se for, então está tudo correto para imprimir um bilhete. Se não for, imprime uma mensagem de erro. EXERCÍCIO 2.32 Nessa versão de printTicket também fazemos algo ligeiramente diferente com os campos total e balance. Compare os códigos e veja se você pode dizer quais são as diferenças. Verifique sua compreensão experimentando no BlueJ. * * * 12. Um exemplo de instrução condicional adicional O método printTicket possui a seguinte instrução: balance -= price; O operador ‘-=‘ subtrai da variável do lado esquerdo o valor da expressão do lado esquerdo. EXERCÍCIO 2.33 Depois que um bilhete foi impresso, poderia o valor no campo balance ser ajustado para um valor negativo subtraindo price dele? Justifique sua resposta. * * * 13. Variáveis locais O método refundBalance uma declaração e três instruções. A declaração ilustra um novo tipo de variável: variável local. Uma variável local é uma variável declarada e utilizada dentro de um único método. Seu escopo e tempo de vida estão limitados aos do método. As declarações de variáveis locais se parecem com as declarações de campo, mas elas nunca tem private ou public como parte delas. Os construtores também podem ter variáveis locais. * * * 13. Exercícios EXERCÍCIO 2.34 Por que a versão seguinte de refundBalance não fornece os mesmos resultados que a original? public int refundBalance() { balance = 0; return balance; } * * * 13. Exercícios EXERCÍCIO 2.35 O que acontece se você tenta compilar a classe TicketMachine com a seguinte versão de refundBalance? public int refundBalance() { return balance; balance = 0; } O que você sabe sobre instruções de retorno que ajudam a explicar por que essa versão não compila. * * * 14. Campos, parâmetros e variáveis locais Já vimos três tipos de variáveis: Campos; Parâmetros formais Variáveis locais Todos os três tipos de variáveis são capazes de armazenar um valor que é apropriado para seu tipo definido. Os campos são declarados fora dos construtores e métodos. Os campos são utilizados para armazenar dados que persistem por toda a vida de um objeto. Como tal, eles mantêm o estado atual do objeto. Os campos têm escopo de classe: sua acessibilidade se estende por toda a classe e podem ser utilizados em qualquer um dos construtores ou métodos da classe em que eles são declarados. Enquanto forem definidos como private, os campos não podem ser acessados de fora de sua classe definidora. * * * 14. Campos, parâmetros e variáveis locais Os parâmetros formais e as variáveis locais persistem somente durante o período em que um construtor ou método executa. Os parâmetros formais são definidos no cabeçalho de um construtor ou método. Os parâmetros formais têm um escopo que é limitado a seu construtor ou ao seu método definidor. Variáveis locais são definidas dentro do corpo de um construtor ou método. As variáveis locais devem ser inicializadas antes de serem utilizadas em uma expressão – elas não recebem um valor padrão. As variáveis locais não são acessíveis em nenhum lugar fora do bloco em que elas são definidas. * * * 14. Exercícios Exercício 2.36 Adicione um novo método, emptyMachine, que é projetado para o esvaziamento da máquina de vender bilhetes. Ele deve retornar o total e redefinir total como zero. Exercício 2.37 emptyMachine é um método de acesso, um método modificador ou ambos? Exercício 2.38 Reescreva o método printTicket de modo que declare uma variável local amountLeftToPay. Ele deve ser inicializado para conter a diferença entre price e balance. Reescreva o teste na instrução condicional para verificar o valor de amountLeftToPay. Se seu valor for menor ou igual a zero, um bilhete deve ser impresso, caso contrário uma mensagem de erro deverá ser impressa declarando a quantidade ainda exigida. Teste sua versão para assegurar que se comporte exatamente da mesma maneira que a versão original. * * * 15. Resumo da máquina de vender bilhetes aprimorada Foram introduzidas duas novas construções de linguagem: A instrução condicional. As variáveis locais. Uma instrução condicional nos permite realizar um teste e, depois, com base no resultado desse teste, realizar uma ou outra de duas ações dinstintas. As variáveis locais nos permitem calcular e armazenar valores temporários dentro de um construtor ou método. * * * 16 Revisando um exemplo familiar Abra o projeto labclasses do capítulo 1. Edite a classe Student. Quantos e quais campos têm a classe Student? A classe contém três campos: name, id e credits. Cada um deles é inicializado no único construtor. Cada um dos campos tem um método de acesso get – associado, mas somente name e credits possuem métodos modificadores. O que isso significa? * * * 16 Revisando um exemplo familiar O método getLoginName ilustra um novo recurso: public String getLoginName() { return name.substring(0,4) + id.substring(0,3); } Os campo name e id são strings e a classe String tem um método de acesso, substring, com a seguinte assinatura: public String substring(int beginIndex, int endIndex) * * * 16 Revisando um exemplo familiar O método substring retorna uma nova string contendo os caracteres de beginIndex a (endIndex-1) dessa string. Um valor de índice zero representa o primeiro caractere de uma string. O método getLoginName pega os quatro primeiros caracteres da string name e os primeiros três caracteres da string id e os concatena para formar uma nova string. * * * 16 Exercícios Exercício 2.39 Desenhe uma figura da forma mostrada na Figura 2.3 representando o estado inicial de um objeto Student seguindo sua construção com os seguintes valores de parâmetros reais: new Student(“Benjamin Jonson”,”738321”) Exercício 2.40 O que seria retornado por getLoginName para um aluno com o campo name igual a “Henry Moore” e o id igual a “557214”? Exercício 2.41 Crie um Student com name “djb” e id “859012”. O que acontece quando getLoginName é chamado sobre esse aluno? Por que isso acontece? * * * 16 Exercícios Exercício 2.42 A classe String define um método um método de acesso length com a seguinte assinatura: /** * Retorna o número de caracteres nessa string. */ public int length() Adicione instruções condicionais ao construtor de Student para imprimir uma mensagem de erro se o comprimento do parâmetro fullName tiver menos de quatro caracteres ou o comprimento do parâmetro studentId tiver menos de três caracteres. Mas o construtor ainda deve utilizar esses parâmetros para configurar os campos name e id, mesmo que a mensagem de erro seja impressa. Exercício 2.43 (Exercício de Desafio) Modifique o método getLoginName de Student de modo que gere sempre um nome de login, mesmo que qualquer um dos campos name e id não sejam suficientemente longos. Para strings mais curtas do que o comprimento requerido, utilize a string inteira. * * * 17. Resumo Termos inseridos neste capítulo Campo Comentário Construtor Escopo Tempo de vida Instrução de atribuição Método de acesso Método modificador println Instrução condicional Expressão booleana Variável local Variável de instância Assinatura de método Corpo de método Instrução de retorno * * * 17. Exercícios Exercício 2.44 Abaixo está a estrutura básica para uma classe Book, que pode ser achada nos projetos do livro. A estrutura básica já define dois campos e um construtor para inicializar os campos. Nesse exercício e nos próximos, você adicionará mais recursos à estrutura básica dessa classe. Adicione dois métodos de acesso à classe – getAuthor e getTitle – que retornam os campos author e title como seus respectivos resultados. Teste sua classe criando algumas instâncias e chamando os métodos. Exercício 2.45 Adicione dois métodos, printAuthor e printTitle, à estrutura básica da classe Book. Devem ser impressos os campos de autor e de título, respectivamente, na janela de terminal. * * * 17. Exercícios Exercício 2.46 Adicione mais um campo, pages, à classe Book para armazenar o número de páginas. Esse deve ser do tipo int e seu valor inicial deve ser passado para o único construtor junto com as strings author e title. Inclua um método de acesso getPages apropriado para esse campo. Exercício 2.47 Adicione um método, printDetails, à classe Book. Isso deve imprimir detalhes do autor, título e páginas na janela de terminal. Você escolhe como os detalhes são formatados. Por exemplo, todos os três itens poderiam ser impressos em uma única linha ou cada um poderia ser impresso em uma linha separada. Você também pode escolher incluir algum texto explicativo para ajudar um usuário a determinar qual é o autor e qual é o título, por exemplo: Title: Robison Crusoe, Author: Daniel Defoe, Pages: 232 * * * 17. Exercícios Exercício 2.48 Adicione mais um campo, refNumber, para a classe Book. Esse campo pode armazenar um número de referência para uma biblioteca, por exemplo. Ele deve ser de tipo String e ser inicializado com a string de comprimento zero (“”) no construtor, pois seu valor inicial não é passado em um parâmetro para o construtor. Em vez disso, defina um método modificador para ele com a seguinte assinatura: Public void setRefNumber(String ref) O corpo desse método deve atribuir o valor do parâmetro ao campo refNumber. Adicione um método de acesso getRefNumber correspondente para ajudá-lo a verificar se o método modificador funciona corretamente. * * * 17. Exercícios Exercício 2.49 Modifique seu método printDetails para incluir a impressão do número de referência. Entretanto, o método deve imprimir o número de referência somente se tiver sido configurado – isso é, se a string refNumber tiver um comprimento diferente de zero. Se ela tiver sido configurada, então imprima a string “ZZZ” no lugar. Dica: Utilize uma instrução condicional cujo teste chama o método length na string refNumber. Exercício 2.50 Modifique seu método modificador setRefNumber de modo que configure o campo refNumber somente se o parâmetro for uma string de pelo menos três caracteres. Se for inferior a três, imprima uma mensagem de erro e deixe o campo inalterado. * * * 17. Exercícios Exercício 2.51 Adicione um campo inteiro, borrowed, à classe Book. Isso mantém uma contagem do número de vezes que o livro foi emprestado. Adicione um método modificador, borrow, à classe. Esse deve incrementar o campo de 1 toda vez que ele for chamado. Inclua um método de acesso, getBorrowed, que retorna o valor desse novo campo como seu resultado. Modifique printDetails de que inclua o valor desse campo com um trecho de texto explicativo. Exercício 2.52 (Exercício de desafio) Crie um novo projeto, heater exercise, no BlueJ. Edite os detalhes na descrição do projeto – a nota de texto que você vê no diagrama. Crie uma classe, Heater, que contenha um único campo inteiro, temperature. Defina um construtor que não aceite nenhum parâmetro. O campo temperature deve ser configurado com o valor 15 no construtor. Defina os métodos modificadores warmer e cooler, cujo efeito é aumentar ou diminuir o valor da temperatura de 5° respectivamente. Defina um método de acesso para retornar o valor de temperature. * * * 17. Exercícios Exercício 2.53 (Exercício de desafio) Modifique sua classe Heater para definir três novos campos inteiros: min, max e increment. Os valores de min e max devem ser configurados por parâmetros passados para o construtor. O valor de increment deve ser configurado como 5 no construtor. Modifique as definições de warmer e cooler de modo que utilizem o valor de increment em vez de um valor explícito 5. Antes de prosseguir com esse exercício, verifique se tudo funciona como antes. Agora modifique o método warmer de modo que não permita que a temperatura seja configurada como um valor maior que max. De maneira semelhante, modifique cooler de modo que não permita que temperature seja configurado com um valor menor que min. Verifique se a classe funciona adequadamente. Agora adicione um método, setIncrement que recebe um único parâmetro inteiro e o utiliza para configurar o valor de increment. Mais uma vez, teste se a classe funciona conforme o esperado criando alguns objetos Heater no BlueJ. As coisas ainda funcionam conforme o esperado se um valor negativo for passado para o método setIncrement? Adicione uma verificação a esse método para evitar que um valor negativo seja atribuído a increment.