Você pode usar um método parametrizado para adicionar um novo recurso à classe Vehicle: a possibilidade de calcular a quantidade de combustível necessária para co- brir uma determinada distância. Esse novo método se chama fuelNeeded( ). Ele rece- be o número de milhas que você quer percorrer e retorna quantos galões de gasolina são necessários. O método fuelNeeded( ) é definido assim:
double fuelNeeded(int miles) { return (double) miles / mpg; }
Observe que esse método retorna um valor de tipo double. Isso é útil, já que a quan- tidade de combustível necessária para cobrir uma determinada distância pode não ser um número inteiro. A classe Vehicle completa com a inclusão de fuelNeeded( ) é mostrada aqui:
/*
Adiciona um método parametrizado que calcula o
combustível necessário para cobrir uma determinada distância. */
class Vehicle {
Este método tem dois parâmetros.
int passengers; // número de passageiros
int fuelCap; // capacidade de armazenamento de combustível em galões int mpg; // consumo de combustível em milhas por galão
// Retorna a autonomia. // int range() {
return mpg * fuelCap; }
// Calcula o combustível necessário para cobrir uma determinada // distância.
double fuelNeeded(int miles) { return (double) miles / mpg; }
}
class CompFuel {
public static void main(String[] args) { Vehicle minivan = new Vehicle(); Vehicle sportscar = new Vehicle(); double gallons;
int dist = 252;
// atribui valores a campos de minivan minivan.passengers = 7;
minivan.fuelCap = 16; minivan.mpg = 21;
// atribui valores a campos de sportscar sportscar.passengers = 2;
sportscar.fuelCap = 14; sportscar.mpg = 12;
gallons = minivan.fuelNeeded(dist);
System.out.println("To go " + dist + " miles minivan needs " + gallons + " gallons of fuel.");
gallons = sportscar.fuelNeeded(dist);
System.out.println("To go " + dist + " miles sportscar needs " + gallons + " gallons of fuel.");
} }
A saída do programa é a seguinte:
To go 252 miles minivan needs 12.0 gallons of fuel. To go 252 miles sportscar needs 21.0 gallons of fuel.
Verificação do progresso
1. Quando uma variável de instância ou um método deve ser acessado por in- termédio de uma referência de objeto com o uso do operador ponto? Quando uma variável ou método pode ser usado diretamente?
2. Explique a diferença entre um argumento e um parâmetro.
3. Explique as duas maneiras pelas quais um método pode retornar para seu chamador.
Respostas:
1. Quando uma variável de instância for acessada por um código que não faz parte da classe
em que ela foi definida, isso deve ser feito por intermédio de um objeto, com o uso do ope- rador ponto. Quando uma variável de instância for acessada por um código que faz parte de sua classe, ela pode ser referenciada diretamente. O mesmo se aplica aos métodos.
2. Um argumento é um valor que é passado para um método quando este é chamado. Um
parâmetro é uma variável definida por um método que recebe o valor do argumento.
3. Podemos fazer um método retornar com o uso da instrução return. Se o método tiver
tipo de retorno void, também retornará quando sua chave de fechamento for alcançada. Métodos não void devem retornar um valor, logo, o retorno pela chegada na chave de fechamento não é uma opção.
TENTE ISTO 4-1
Criando uma classe de ajuda
HelpClassDemo.java
Se alguém tentasse resumir a essência da classe em uma frase, ela poderia ser esta: uma classe encapsula funcionalidade. É claro que às vezes o truque é saber onde uma funcionalidade termina e outra começa. Como regra geral, você vai querer que suas classes sejam os blocos de construção do aplicativo final. Para que isso ocorra, cada classe deve representar uma única unidade funcional exe- cutando ações claramente delimitadas. Portanto, você vai querer que suas classes sejam tão pequenas quanto possível – mas não menores do que isso! Ou seja, classes que contêm funcionalidade demais confundem e desestruturam o código, mas classes que contêm muito pouca funcionalidade são fragmentadas. Qual é o equilíbrio? É nesse ponto que a ciência da programação se torna a arte de progra- mar. Felizmente, a maioria dos programadores descobre que esse ato de equilí- brio se torna mais fácil com a experiência.
Para começar a ganhar essa experiência, você converterá o sistema de ajuda da seção Tente isto 3-3 do capítulo anterior em uma classe Help. Vejamos por que essa é uma boa ideia. Em primeiro lugar, o sistema de ajuda define apenas uma unidade lógica. Ele simplesmente exibe a sintaxe das instruções de controle Java. Logo, sua funcionalidade é compacta e bem definida. Em segundo lugar, inserir a ajuda em uma classe é uma abordagem esteticamente amigável. Sempre que você quiser oferecer o sistema de ajuda a um usuário, só terá de instanciar um objeto de sistema de ajuda. Para concluir, já que a ajuda está encapsulada, pode ser atua- lizada ou alterada sem causar efeitos colaterais indesejados nos programas que a usarem.
PASSO A PASSO
1. Crie um novo arquivo chamado HelpClassDemo.java. Para evitar digitação, você pode copiar o arquivo da seção Tente isto 3-3, Help3.java, para Help- ClassDemo.java.
2. Para converter o sistema de ajuda em uma classe, primeiro você deve deter- minar precisamente o que compõe o sistema. Por exemplo, em Help3.java, há código para a exibição de um menu, a inserção da escolha do usuário, a procura de uma resposta válida e a exibição de informações sobre o item se- lecionado. O programa também entra em laço até a letra q ser pressionada. Se você pensar bem, está claro que o menu, a procura por uma resposta válida e a exibição de informações são parte integrante do sistema de ajuda, mas o modo como a entrada do usuário é obtida e decidir se solicitações repetidas devem ser processadas não são. Logo, você criará uma classe que exibirá as informações de ajuda, exibirá o menu e procurará uma seleção válida. Seus métodos se chamarão helpOn( ), showMenu( ) e isValid( ), respectivamente. 3. Crie o método helpOn( ) como mostrado aqui:
// Exibe a ajuda. void helpOn(int what) { switch(what) { case '1': System.out.println("The if:\n"); System.out.println("if(condition) statement;"); System.out.println("else statement;"); break; case '2': System.out.println("The switch:\n"); System.out.println("switch(expression) {"); System.out.println(" case constant:"); System.out.println(" statement sequence"); System.out.println(" break;"); System.out.println(" // ..."); System.out.println("}"); break; case '3': System.out.println("The for:\n");
System.out.print("for(init; condition; iteration)"); System.out.println(" statement;"); break; case '4': System.out.println("The while:\n"); System.out.println("while(condition) statement;"); break; case '5': System.out.println("The do-while:\n"); System.out.println("do {"); System.out.println(" statement;");
System.out.println("} while (condition);"); break;
case '6':
System.out.println("break; or break label;"); break;
case '7':
System.out.println("The continue:\n");
System.out.println("continue; or continue label;"); break;
}
System.out.println(); }
4. Em seguida, crie o método showMenu( ):
// Exibe o menu. void showMenu() { System.out.println("Help on:"); System.out.println(" 1. if"); System.out.println(" 2. switch"); System.out.println(" 3. for"); System.out.println(" 4. while"); System.out.println(" 5. do-while"); System.out.println(" 6. break"); System.out.println(" 7. continue\n"); System.out.print("Choose one (q to quit): "); }
5. Crie o método isValid( ), mostrado aqui:
// Retorna true se ch for uma seleção válida. boolean isValid(int ch) {
if(ch < '1' | ch > '7' & ch != 'q') return false; else return true;
}
6. Reúna os métodos anteriores na classe Help, listada abaixo:
class Help {
// Exibe a ajuda. void helpOn(int what) { switch(what) { case '1': System.out.println("The if:\n"); System.out.println("if(condition) statement;"); System.out.println("else statement;"); break; case '2': System.out.println("The switch:\n"); System.out.println("switch(expression) {"); System.out.println(" case constant:"); System.out.println(" statement sequence"); System.out.println(" break;");
System.out.println(" // ..."); System.out.println("}"); break;
case '3':
System.out.println("The for:\n");
System.out.print("for(init; condition; iteration)"); System.out.println(" statement;"); break; case '4': System.out.println("The while:\n"); System.out.println("while(condition) statement;"); break; case '5': System.out.println("The do-while:\n"); System.out.println("do {"); System.out.println(" statement;");
System.out.println("} while (condition);"); break;
case '6':
System.out.println("The break:\n");
System.out.println("break; or break label;"); break;
case '7':
System.out.println("The continue:\n");
System.out.println("continue; or continue label;"); break; } System.out.println(); } // Exibe o menu. void showMenu() { System.out.println("Help on:"); System.out.println(" 1. if"); System.out.println(" 2. switch"); System.out.println(" 3. for"); System.out.println(" 4. while"); System.out.println(" 5. do-while"); System.out.println(" 6. break"); System.out.println(" 7. continue\n"); System.out.print("Choose one (q to quit): "); }
// Retorna true se ch for uma seleção válida. boolean isValid(int ch) {
if(ch < '1' | ch > '7' & ch != 'q') return false; else return true;
} }
7. Para concluir, reescreva o método main( ) da seção Tente isto 3-3, para que ele use a nova classe Help. Chame essa classe de HelpClassDemo.java. A listagem completa de HelpClassDemo.java é mostrada a seguir:
/*
Tente isto 4-1
Converte o sistema de ajuda da seção Tente isto 3-3 em uma classe Help.
*/
class Help {
// Exibe a ajuda. void helpOn(int what) { switch(what) { case '1': System.out.println("The if:\n"); System.out.println("if(condition) statement;"); System.out.println("else statement;"); break; case '2': System.out.println("The switch:\n"); System.out.println("switch(expression) {"); System.out.println(" case constant:"); System.out.println(" statement sequence"); System.out.println(" break;"); System.out.println(" // ..."); System.out.println("}"); break; case '3': System.out.println("The for:\n");
System.out.print("for(init; condition; iteration)"); System.out.println(" statement;"); break; case '4': System.out.println("The while:\n"); System.out.println("while(condition) statement;"); break; case '5': System.out.println("The do-while:\n"); System.out.println("do {"); System.out.println(" statement;");
System.out.println("} while (condition);"); break;
case '6':
System.out.println("The break:\n");
System.out.println("break; or break label;"); break;
case '7':
System.out.println("The continue:\n");
System.out.println("continue; or continue label;"); break; } System.out.println(); } // Exibe o menu. void showMenu() { System.out.println("Help on:"); System.out.println(" 1. if"); System.out.println(" 2. switch"); System.out.println(" 3. for"); System.out.println(" 4. while"); System.out.println(" 5. do-while"); System.out.println(" 6. break"); System.out.println(" 7. continue\n"); System.out.print("Choose one (q to quit): "); }
// Retorna true se ch for uma seleção válida. boolean isValid(int ch) {
if(ch < '1' | ch > '7' & ch != 'q') return false; else return true;
} }
class HelpClassDemo {
public static void main(String[] args) throws java.io.IOException {
char choice, ignore; Help hlpobj = new Help();
for(;;) { do {
hlpobj.showMenu();
choice = (char) System.in.read();
do {
ignore = (char) System.in.read(); } while(ignore != '\n');
CONSTRUTORES
Nos exemplos anteriores, as variáveis de instância de cada objeto Vehicle tiveram de ser configuradas manualmente com o uso de uma sequência de instruções, como:
minivan.passengers = 7; minivan.fuelCap = 16; minivan.mpg = 21;
Uma abordagem como essa nunca seria usada em um código Java escrito profissio- nalmente. Além de ser propensa a erros (você pode se esquecer de configurar um dos campos), há uma maneira melhor de executar essa tarefa: o construtor.
Um construtor inicializa um objeto quando este é criado. Ele tem o mesmo nome de sua classe e é sintaticamente semelhante a um método. No entanto, os cons- trutores não têm um tipo de retorno explícito. Normalmente, usamos um construtor para fornecer valores iniciais para as variáveis de instância definidas pela classe ou para executar algum outro procedimento de inicialização necessário à criação de um objeto totalmente formado.
Todas as classes têm construtores, mesmo quando não definimos um, porque Java fornece automaticamente um construtor padrão. No entanto, quando definimos nosso próprio construtor, o construtor padrão não é mais usado.
Aqui está um exemplo simples que usa um construtor:
// Um construtor simples. class MyClass { int x; MyClass() { x = 10; } } class ConsDemo {
public static void main(String[] args) { Este é o construtor de MyClass.
if(choice = = 'q') break; System.out.println("\n"); hlpobj.helpOn(choice); } } }
Quando você testar o programa, verá que ele é funcionalmente o mesmo de antes. A vantagem dessa abordagem é que agora você tem um componente de sistema de ajuda que pode ser reutilizado sempre que necessário.
MyClass t1 = new MyClass(); MyClass t2 = new MyClass();
System.out.println(t1.x + " " + t2.x); }
}
Nesse exemplo, o construtor de MyClass é
MyClass() { x = 10; }
Esse construtor atribui o valor 10 à variável de instância x de MyClass. Ele é chama- do por new quando um objeto é criado. Por exemplo, na linha
MyClass t1 = new MyClass();
o construtor MyClass( ) é chamado e o objeto resultante é atribuído a t1, com t1.x recebendo o valor 10. O mesmo ocorre para t2. Após a construção, t2.x tem o valor 10. Portanto, a saída do programa é
10 10