Mudanças entre as edições de "Pensamento Computacional - Métodos no Java"
Linha 215: | Linha 215: | ||
Na realidade, este conceito de variáveis locais se estende a qualquer bloco. | Na realidade, este conceito de variáveis locais se estende a qualquer bloco. | ||
+ | |||
+ | ==Exercício== | ||
+ | |||
+ | Considere o seguinte problema (já repassado em avaliação): | ||
+ | |||
+ | import java.util.Locale; | ||
+ | import java.util.Scanner; | ||
+ | |||
+ | public class A2T4 { | ||
+ | |||
+ | static String senha1, msgUsuario1; | ||
+ | static String senha2, msgUsuario2; | ||
+ | static String senhaLida; | ||
+ | static Scanner teclado; | ||
+ | |||
+ | public static void imprimeMenu() { | ||
+ | |||
+ | } | ||
+ | |||
+ | public static void modoAdministrador() { | ||
+ | /* implemente aqui o código associado ao administrador */ | ||
+ | |||
+ | } | ||
+ | |||
+ | public static void trataUsuario1() { | ||
+ | /* Implemente aqui o código dedicado ao usuário 1 */ | ||
+ | System.out.println(msgUsuario1); | ||
+ | } | ||
+ | |||
+ | public static void trataUsuario2() { | ||
+ | /* Implemente aqui o código dedicado ao usuário 2 */ | ||
+ | System.out.println(msgUsuario2); | ||
+ | } | ||
+ | |||
+ | public static void main(String[] args) { | ||
+ | teclado = new Scanner(System.in); | ||
+ | teclado.useLocale(Locale.ENGLISH); | ||
+ | |||
+ | |||
+ | senha1 = "abc"; | ||
+ | msgUsuario1 = "Alô usuário 1!"; | ||
+ | senha2 = "def"; | ||
+ | msgUsuario2 = "Alô usuário 2!"; | ||
+ | |||
+ | |||
+ | while (true) { | ||
+ | System.out.println("Entre com uma senha"); | ||
+ | senhaLida = teclado.nextLine(); | ||
+ | |||
+ | if (senhaLida.equals("admin123")) { | ||
+ | /* Implemente aqui o código de modo administrador */ | ||
+ | modoAdministrador(); | ||
+ | } else if (senhaLida.equals(senha1)) { | ||
+ | trataUsuario1();; | ||
+ | } else if (senhaLida.equals(senha2)) { | ||
+ | /* Implemente aqui o código dedicado ao usuário 2 */ | ||
+ | trataUsuario2(); | ||
+ | } else { | ||
+ | System.out.println("Senha não registrada!!!"); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } |
Edição das 20h01min de 10 de novembro de 2023
Objetivos da Aula
- Conceituar métodos, parâmetros e valor de retorno no Java;
- Definir, declarar e chamar métodos no Java;
- Aplicar métodos para resolver subproblemas de um grande problema;
O que é um método no Java
Uma método (também pode ser visto como uma função) é um "bloco de código" que resolve um dado problema específico, que possui um nome associado e que pode ser chamado quando necessário. Ao final da execução do código do método, o fluxo de execução retorna para quem "chamou" o método.
Exemplo: para calcular o seno de um ângulo chamamos um método para resolver o problema específico: "calcular um seno". Dados de entrada devem ser fornecidos, no caso o ângulo. O dado de saída é o seno computado deste ângulo.
Notar que a função permite REAPROVEITAR o código. Não precisamos a todo momento reescrever um código que computa o seno. Basta chamar a função.
EXEMPLO: Desenhar um retângulo no terminal exige um certo número de linhas de código. É uma tarefa bem específica que poderia ser "ENCAPSULADA" em um método. Seria algo da forma:
import java.util.Scanner;
public class MetodoDesenhaRetangula {
public static void DesenhaRetangulo() {
for(int i = 0; i < 10; i++ ) {
for(int j = 0; j < 20; j++ ) {
System.out.print("X");
}
System.out.println("");
}
System.out.println("");
}
public static void main(String[] args) {
System.out.println("Vou desenhar um retangulo...");
DesenhaRetangulo();
System.out.println("Vou desenhar um outro retangulo...");
DesenhaRetangulo();
}
}
DISCUSSÃO: Neste exemplo existem dois métodos: o main() e DesenhaRetangulo(). Podemos dizer que ao executar o programa, o método main() é AUTOMATICAMENTE chamado. Uma após outra, as instruções do método main() são executadas. Inicialmente a instrução:
System.out.println("Vou desenhar um retangulo...");
Esta instrução é uma CHAMADA ao método println()... Este método está na biblioteca e tem como objetivo imprimir mensagens na tela.
Na sequência é executada a seguinte instrução:
DesenhaRetangulo();
Esta instrução TAMBÉM é uma chamada de um método. OBSERVE o significado de CHAMAR: é o desvio do fluxo de execução do programa para o código do método. O código será executado até o final quando então o fluxo de execução retorna para QUEM/QUE chamou.
Observe que a implementação do método DesenhaRetângulo() foi fornecida pelo próprio programador. Já o método println() já está implementado na biblioteca.
Após a chamada do DesenhaRetângulo(), novamente é chamado o método println:
System.out.println("Vou desenhar um outro retangulo...");
E finalmente é chamado mais uma vez o método DesenhaRetangulo();.
Trata-se de um exemplo simples mostrando que podemos chamar quantas vezes quisermos um determinado código de um método.
Parâmetros de um método
No exemplo anterior, o método DesenhaRetangulo() cumpre bem a sua tarefa de desenhar um retângulo. Entretanto, o que podemos fazer se desejarmos configurar o número de linhas e a largura do retângulo?
Aqui entra o conceito de PARAMETRIZAR o método, ou seja, repassar valores para que ele possa ser PERSONALIZADO ("customized" em inglês).
Vamos a um exemplo onde PARAMETRIZAMOS a LARGURA do retângulo:
import java.util.Scanner;
public class MetodoDesenhaRetangula {
public static void DesenhaRetanguloLarguraConfiguravel(int largura) {
for(int i = 0; i < 10; i++ ) {
for(int j = 0; j < largura; j++ ) {
System.out.print("X");
}
System.out.println("");
}
System.out.println("");
}
public static void main(String[] args) {
System.out.println("Vou desenhar um retangulo...");
DesenhaRetanguloLarguraConfiguravel(10);
System.out.println("Vou desenhar um outro retangulo...");
DesenhaRetanguloLarguraConfiguravel(20);
}
}
DISCUSSÃO: Agora conseguimos repassar a largura que queremos ao chamar o método DesenhaRetanguloLarguraConfiguravel(). Observe que o valor repassado (no caso 10) é COPIADO para o parâmetro FORMAL largura, ANTES do método ser chamado ("invoked" em inglês). Desta forma, quando o código do método começa a ser executado, o parâmetro largura conterá o valor 10. Observe que "largura" é uma variável especial que serve como interface entre QUEM CHAMA e o CHAMADO.
Sintaxe do método com PARÂMETROS
Observe que os parâmetros são declarados dentro de parênteses, tal como se fossem variáveis. Vamos modificar o código acima para que sejam passados dois parâmetros: largura e altura:
import java.util.Scanner;
public class MetodoDesenhaRetangula {
public static void DesenhaRetanguloLarguraConfiguravel(int largura, int altura) {
for(int i = 0; i < altura; i++ ) {
for(int j = 0; j < largura; j++ ) {
System.out.print("X");
}
System.out.println("");
}
System.out.println("");
}
public static void main(String[] args) {
System.out.println("Vou desenhar um retangulo...");
DesenhaRetanguloLarguraConfiguravel(10, 10);
System.out.println("Vou desenhar um outro retangulo...");
DesenhaRetanguloLarguraConfiguravel(20, 15);
}
}
O detalhe de como é realizada a chamada e passagem de parâmetros é mostrada abaixo. Em vermelho, mostrando a cópia de valores para os parâmetros formais largura e altura.
Exercício 1
Implemente no método main() um código que lê pelo teclado os valores da altura e largura desejada do retângulo. Na sequência o método de desenho de retângulo deve ser chamado com os valores lidos.
Exercício 2
O problema resolvido pelo método de desenho de retângulo poderia ainda ser decomposto no desenho de linha. Crie um método de desenho de linha e chame-o a partir do método de desenho de retângulo.
Valor de Retorno de um Método
Os parâmetros do método podem ser vistos como DADOS DE ENTRADA para o código do método. Em várias situações o método pode produzir um valor que deverá ser RETORNADO para o código que chamou. Vamos a um exemplo simples de um método para computar a média de 3 números:
PROBLEMA> Computar a média de 3 números reais. DADOS DE ENTRADA (parâmetros): os 3 números SAÍDA: média computada
import java.util.Scanner;
public class MediaTresNumeros {
public static double MediaTresNumeros(double num1, double num2, double num3) {
double mediaCalculada;
mediaCalculada = (num1 + num2 + num3) / 3;
return mediaCalculada;
}
public static void main(String[] args) {
double media;
System.out.println("Vou calcular a media de 3 números...");
media = MediaTresNumeros ( 10.5, 9.5, 10.0 );
System.out.println("Media de 10.5, 9.5 e 10.0 é " + media);
}
}
DISCUSSÂO: Este exemplo é puramente didático. Possivelmente não se justificaria um método para este cálculo. O método aceita os 3 parâmetros de entrada e retorna o valor da média calculada. Observe que em termos de fluxo de execução, um método sempre retorna (pelo menos os "bem comportados"). Entretanto, neste caso acompanha um VALOR de retorno que é o resultado do processamento. Este resultado, em geral, deverá ser armazenado em algum local, no caso, na variável media do método chamador (main()).
Sintaxe associada ao retorno
Um ponto interessante a ser observado é que na implementação do método, o TIPO DE RETORNO deve ser informado. Se não retornar valor então será usada a palavra reservada "void". Confira nos exemplos de desenho de retângulo, onde não era retornado nenhum valor. Se o método retorna um valor, então o TIPO DE RETORNO é explicitado. Veja o detalhe:
DISCUSSÃO: Observe que o método de cálculo de média usa a instrução 'return' acompanhada do valor a ser retornado, no caso, o conteúdo da variável 'mediaCalculada'. Normalmente esta instrução está no final do método, mas não necessariamente. Podem existir inclusive várias instruções 'return' em um mesmo método.
Exercício 3
Implemente um método Java para cálculo da área de um círculo. Quais seriam os parâmetros deste método? Qual seria o valor de retorno?
Exercício 4
Implemente um método Java para cálculo da área de um anel composto por dois círculos. Reutilize o método acima.
Exercício 5
Implemente um método Java para computar o fatorial de um número. Quais seriam os parâmetros deste método? Qual seria o retorno? No programa principal, mostre em uma única instrução como seria a computação da soma de dois fatoriais:
Variáveis locais
Variáveis declaradas no bloco de código do método são LOCAIS no sentido que são "vistas" somente pelo código do método. O tempo de vida destas variáveis é o tempo em que a o método se executa. Assim que houver um retorno para quem chamou (invocou), esta variável deixa de existir.
DISCUSSÃO: No exemplo acima observe que a variável mediaCalculada é declarada dentro do método MediaTresNumeros(). Desta forma, o método main() não "enxerga" esta variável, que somente será criada quando o método for invocado e destruída quando o método retornar.
É interessante observar que a variável media, declarada dentro do main() também é uma variável local. Como o método main() é invocado pelo "sistema" quando o programa começa a ser executado, esta variável tem um tempo de vida correspondente ao tempo em que o programa se executa, sendo destruída quando o main() retorna.
Na realidade, este conceito de variáveis locais se estende a qualquer bloco.
Exercício
Considere o seguinte problema (já repassado em avaliação):
import java.util.Locale; import java.util.Scanner;
public class A2T4 {
static String senha1, msgUsuario1; static String senha2, msgUsuario2; static String senhaLida; static Scanner teclado;
public static void imprimeMenu() {
} public static void modoAdministrador() { /* implemente aqui o código associado ao administrador */
}
public static void trataUsuario1() { /* Implemente aqui o código dedicado ao usuário 1 */ System.out.println(msgUsuario1); }
public static void trataUsuario2() { /* Implemente aqui o código dedicado ao usuário 2 */ System.out.println(msgUsuario2); }
public static void main(String[] args) { teclado = new Scanner(System.in); teclado.useLocale(Locale.ENGLISH);
senha1 = "abc"; msgUsuario1 = "Alô usuário 1!"; senha2 = "def"; msgUsuario2 = "Alô usuário 2!";
while (true) { System.out.println("Entre com uma senha"); senhaLida = teclado.nextLine();
if (senhaLida.equals("admin123")) { /* Implemente aqui o código de modo administrador */ modoAdministrador(); } else if (senhaLida.equals(senha1)) { trataUsuario1();; } else if (senhaLida.equals(senha2)) { /* Implemente aqui o código dedicado ao usuário 2 */ trataUsuario2(); } else { System.out.println("Senha não registrada!!!"); } } }
}