Cursos: Análise, Ciência da Computação e Sistemas de Informação Programação I - Prof. Aníbal Notas de aula 2 DEFINIÇÃO DE MÉTODOS Todo o processamento que um programa Java faz está definido dentro dos métodos de suas classes. Método, portanto, é a parte da classe que se encarrega de detalhar como as operações serão feitas, utilizando ou não os dados dos seus objetos, representados pelos atributos. São compostos de conjunto de instruções (ou comandos) para a execução das operações necessárias para realizar a tarefa a que o método se propõe. Um método tem a seguinte: Sintaxe: modificadores //instruções } tipo de retorno nome (lista de parâmetros){ onde modificadores – existem vários – já conhecemos dois que indicam visibilidade do método (public e private). Em geral, os métodos devem ser public se quisermos permitir que outras classes utilizem nossa classe, o que é recomendável na maioria dos casos. tipo de retorno - alguns métodos devolvem um resultado a quem o acionou (chamou), cujo tipo deve ser indicado (como os que já conhecemos, int, String, double, ou outro tipo qualquer, que veremos mais adiante, podendo ser, inclusive, um objeto); outros métodos não devolvem nenhum valor específico, caso em que a palavra void deve ser usada em lugar do tipo de retorno. lista de parâmetros – muitos métodos necessitam receber dados para começar seu trabalho, outros não. Cada parâmetro deve ter um tipo e um nome, como, por exemplo (String nome, int quantidade, double taxa) Mesmo que a lista de parâmetros seja vazia, o par de ( ) deve aparecer. As chaves { } delimitam o bloco de código com as instruções. Ex. Voltando à classe Funcionario, vamos definir um de seus métodos, o que simula a mudança de salário de um funcionário para um novo valor. public class Funcionario{ // atributos private String nome; private double salario; private int numeroDeDependentes; // métodos /** Muda o salário do funcionário */ public void mudaSalario(double novoSalario){ salario = novoSalario; } // outros métodos aqui } O método tem um parâmetro de tipo double de nome novoSalario. Através dele é passado o valor do novo salário ao método quando este for acionado (chamado), o qual será atribuído ao atributo salario do objeto. Programação I - Prof. Aníbal - Notas de aula 2 1 Métodos de configuração de atributos (métodos set) Métodos que simplesmente trocam o valor de um atributo por novo valor (como o método mudaSalario) são muito comuns nas classes. Nestes casos, existe um padrão na comunidade Java de usar o verbo inglês set no nome do método, em lugar de outro verbo qualquer. Para seguir esse padrão internacionalmente conhecido, vamos mudar o nome do nosso método para setSalario. /** Muda o salário do funcionário */ public void setSalario(double novoSalario){ salario = novoSalario; } Assim, sempre que a finalidade do método for apenas trocar o conteúdo de um atributo por novo valor, sem outros cálculos ou operações envolvidas, vamos usar o padrão exemplificado no setSalario: o método é sempre public void, o nome do método é sempre a palavra set seguida do nome do atributo, tem um parâmetro de mesmo tipo do atributo e seu bloco de código se resume a uma atribuição do parâmetro ao respectivo atributo. Exercício 2.1. Escreva um método set para permitir a mudança do nome do funcionário. Chamada de método Um método é chamado (acionado) por outro método que está em outra classe ou dentro da própria classe: Sintaxe 1: chamada a partir de outra classe identificador do objeto.nome do método(lista de argumentos); // método com parâmetro identificador do objeto.nome do método( ); // método sem parâmetros Sintaxe 2: chamada de dentro da própria classe nome do método(lista de argumentos); // método com parâmetro nome do método( ); // método sem parâmetros Exemplos de chamadas a partir de outra classe: f1.setSalario(2500.00); f2.setSalario(3235.50); Cada vez que um método A chama um outro método B, ele empresta o controle da execução para esse outro, como mostra a figura abaixo. Ao terminar seu trabalho, o método B devolve o controle para o A. Método A // outras instruções ....... f1.setSalario ( 2500.00); // instrução seguinte ........ f2.setSalario ( 3235.50); // instrução seguinte ....... Método B public void setSalario(double novoSalario) { salario = novoSalario; } Programação I - Prof. Aníbal - Notas de aula 2 2 Passagem de argumentos Além de passar o controle da execução, o método A passa para o B o valor de seu argumento para o parâmetro correspondente do método B (chamamos de argumento o valor que aparece na chamada do método, o qual passará para o parâmetro correspondente. Há outras nomenclaturas usadas). Repare a ilustração : f1.setSalario(2500.00); f2.setSalario(3235.50); public void setSalario(double novoSalario){ salario = novoSalario; } O resultado das duas chamadas é a atribuição dos respectivos valores dos argumentos ao atributo salario dos objetos f1 e f2: f1 Funcionário f2 nome null salario 2500.00 numeroDeDependentes 0 Funcionario nome null salario 3235.50 numeroDeDependentes 0 Exercício 2.2. Dada uma classe Circulo que tem um atributo inteiro raio, escreva o método setRaio. Exercício 2.3. Instancie um círculo e depois mude o valor do seu raio para 3, chamando o método que você acabou de programar. A seguir, mude o raio do mesmo círculo para 5. Desenhe como fica o objeto na memória. Saída de dados Vamos codificar mais um dos métodos de nossa classe Funcionario. public class Funcionario{ private String nome; private double salario; private int numeroDeDependentes; /** Muda o salário do funcionário */ public void setSalario(double novoSalario){ salario = novoSalario; } /** Exibe os dados do funcionário na tela */ public void exibeDados(){ System.out.println(nome); System.out.println(salario); System.out.println(numeroDeDependentes); } } Programação I - Prof. Aníbal - Notas de aula 2 3 Para exibir dados na tela, acionamos (chamamos) o método println aplicado sobre o objeto out da classe System (repare a sintaxe, com o uso dos pontos). Trata-se de uma classe já pronta, fornecida pelo fabricante de Java. Ex: f1.exibeDados(); exibe na tela os valores dos atributos do objeto f1, um em cada linha, como segue: null 2500.0 0 Concatenação de Strings Em Java, podemos concatenar dois Strings através do operador +. Ex: “Bla” + “blu” resultará “Blablu”. Usando esse recurso, podemos melhorar a aparência da saída na tela do nosso método exibeDados( ): public void exibeDados(){ System.out.println("Nome: " + nome); System.out.println("Salário: " + salario); System.out.println("Dependentes: " + numeroDeDependentes); } Exercício 2.4. O que o método acima exibiria para a chamada f2.exibeDados(); ? Veja que, após exibir o que aparece dentro dos parênteses, o método println inicia uma nova linha. Usando o método print em lugar do println, o cursor permanece na mesma linha após a exibição dos dados. public void exibeDados(){ System.out.print("Nome: " + nome + " "); System.out.print("Salário: " + salario + " "); System.out.println("Dependentes: " + numeroDeDependentes); } Exercício 2.5. Para f1.exibeDados( ); como seria a tela resultante? Programação I - Prof. Aníbal - Notas de aula 2 4 Construtores Construtor é um método especial usado para inicializar objetos quando estes são criados. Características: Tem o mesmo nome da classe É automaticamente chamado pelo operador new Não tem tipo de retorno (mas não se escreve void) Ex. Para a classe Funcionario. public Funcionario(String n, double sal, int nd){ nome = n; salario = sal; numeroDeDependentes = nd; } A chamada do construtor é automática, quando o objeto é criado com new. Ex: Funcionario f3 = new Funcionario("Érico Veríssimo", 1655.00, 2); Atenção A única maneira de chamar um construtor é através do new. Não podemos chamar um construtor como fazemos com os demais métodos. Por exemplo, f3.Funcionario("Érico Veríssimo",1655.00,2); // ERRO Exercício 2.6. Escreva um construtor para a classe ContaBancaria, supondo que toda conta deva ser aberta (criada) com um depósito inicial de valor positivo. Exercício 2.7. Escreva um construtor para a classe Carro. Quando um objeto carro é criado, seu tanque de combustível é inicializado em 0. Portanto, o construtor só tem dois parâmetros para receber a placa e o consumo médio. Sobrecarga de métodos ou de construtores Numa mesma classe, dois ou mais métodos podem ter o mesmo nome, desde que tenham tipos ou quantidades de parâmetros diferentes. Chama-se a isso sobrecarga de métodos. A sobrecarga de construtores também existe e é muito usada. Ex. Vamos criar outro construtor que apenas atribui nome e número de dependentes ao funcionário, mas inicializa seu salário em zero. Programação I - Prof. Aníbal - Notas de aula 2 5 public Funcionario(String umNome, int numDep){ nome = umNome; salario = 0; numeroDeDependentes = numDep; } Agora, podemos criar um objeto de duas maneiras, já que a classe tem dois construtores: Funcionario f4 = new Funcionario("Machado de Assis", 3500.0, 1); Funcionario f5 = new Funcionario("Cecília Meirelles", 3); Importante O nome mais os tipos de parâmetros de um método formam a sua assinatura. Dois métodos de mesmo nome, mas tipos de parâmetros diferentes não têm a mesma assinatura. O compilador Java identifica qual o construtor que deve ser acionado, dependendo dos argumentos que são passados para ele na chamada. O mesmo mecanismo vale para métodos sobrecarregados. Se não dotarmos nossa classe de construtor(es), Java adota um construtor padrão (default), sem parâmetros, que atribui valores default aos atributos do objeto. Era o que estava acontecendo com nossa classe Funcionario antes de introduzirmos os construtores. O comando Funcionario f1 = new Funcionario(); estava chamando o construtor padrão. Se dotarmos nossa classe de um ou mais construtores, Java não adotará construtor padrão para ela. Então, a chamada Funcionario f1 = new Funcionario(); passa a ser um erro de compilação, pois não existe mais construtor padrão na classe. Exercício 2.8. Na classe Carro você já tem um construtor de dois parâmetros. Crie um outro construtor (sobrecarga) para Carro, com três parâmetros, que permita inicializar o nível do tanque com qualquer quantidade de combustível. Exercício 2.9. Escreva as duas formas que você tem agora de instanciar um objeto Carro. Classe de teste Nossa classe Funcionario já é útil. Ela pode ser compilada e seus métodos já podem ser chamados a partir de métodos de outras classes (pois foram declarados public). Vamos experimentar isso, criando uma outra classe apenas para testar a classe Funcionario. Uma classe de teste não tem atributos e só tem um método estático (estudaremos mais adiante os métodos estáticos) de nome main que cria objetos da classe que estamos testando chama métodos da classe sendo testada para ver se eles funcionam Programação I - Prof. Aníbal - Notas de aula 2 6 TestaFuncionario +main public class TestaFuncionario{ public static void main(String args[]) { Funcionario f1 = new Funcionario(“Jose Silva”, 2500.0, 1); f1.exibeDados( ); } } Quando mandamos executar uma classe, Java procura o método main desta classe e executa-o. Os outros métodos só executam quando são chamados pelo método main ou por outro método qualquer da própria classe ou de outra classe se ele foi declarado como public. Exercício 2.10. O que acontece (na memória e na tela) quando a classe TestaFuncionario é executada? Na memória: Na tela: Exercício 2.11. Acrescente outras instruções ao método main para criar outro objeto e exibir seus dados. A seguir, para este objeto, altere o seu salário e exiba novamente seus dados. Exercício 2.12. Escreva o método de consulta ao saldo na sua classe ContaBancaria para mostrar na tela o saldo da conta. Exercício 2.13. Escreva uma classe de teste para testar a classe ContaBancaria. Depois, suponha que a classe de teste é executada e desenhe o que acontece na memória e na tela. Programação I - Prof. Aníbal - Notas de aula 2 7 Métodos que retornam um valor (não void) Quando um método termina sua execução, ele devolve o controle da máquina para o método que o chamou. Além disso, um método pode, neste momento, devolver junto um valor. Para que um método devolva um valor: na sua declaração, a palavra void deve ser substituída pelo tipo do valor a ser devolvido pelo método no bloco de código do método deve haver pelo menos um comando return expressão; A instrução return Sintaxe return expressão; // especifica o valor que o método devolve e sai imediatamente do método return; // sai imediatamente do método Métodos de acesso aos atributos – get Para exemplificar métodos não void, vamos começar pelos métodos de acesso aos atributos. Um método de acesso a um atributo private é aquele que tem por finalidade retornar, quando acionado, o valor atual daquele atributo. Usa o verbo get na formação de seu nome. Ex. Vamos dotar a nossa classe Funcionario de três métodos get que devolvem o valor de cada atributo /** Método que devolve o nome do funcionário */ public String getNome(){ return nome; } /** Método que retorna o salário do funcionário */ public double getSalario(){ return salario; } /** Método que retorna o número de dependentes do funcionário */ public int getDependentes(){return numeroDeDependentes;} //Passaremos a codificar métodos get em uma só linha, pela sua simplicidade Então, sempre que a finalidade do método for apenas retornar o valor de um atributo, sem outros cálculos ou operações envolvidas, vamos usar o padrão get: o método é sempre public seguido do tipo a ser devolvido, que corresponde ao tipo do atributo; o nome do método é sempre a palavra get seguida do nome do atributo e o método não tem parâmetro; o seu bloco de código se resume a instrução return nome do atributo; Exercício 2.14. Escreva métodos de acesso aos atributos para a classe Carro Programação I - Prof. Aníbal - Notas de aula 2 8 Chamando métodos não void Ao chamar um método que retorna um valor (não void), a instrução que o chamou deve fazer algo com este valor recebido. Logo, a chamada do método deve estar embutida dentro de uma outra instrução Java. Ex: O método exibeDados( ) da classe Funcionario, reprogramado para chamar os gets da classe: public void exibeDados( ){ System.out.println(“Nome: “ + getNome()); System.out.println(“Salário: “ + getSalario()); System.out.println(“Dependentes: “ + getDependentes()); } Embora todo método possa ser chamado a partir de outro método da própria classe, como mostra o exemplo anterior, a importância dos métodos get é permitir que outras classes tenham acesso aos valores dos atributos privados da classe. Ex: Veja como uma outra classe (a TestaFuncionario) pode acessar conteúdo de um ou mais atributos da classe Funcionario: public class TestaFuncionario{ public static void main(String args[]){ Funcionario f3 = new Funcionario("Augusto dos Anjos", 2700.00, 6); System.out.println("Nome do funcionário: " + f3.getNome()); //mostra só o nome f3.exibeDados(); //exibe todos os três atributos de f3 } } Exercício 2.15. Escreva uma classe de teste para a classe Carro. Nela instancie um objeto Carro e depois escreva uma ou mais instruções que chame(m) um ou mais métodos get da classe. A chamada de um método void constitui uma instrução Java sozinha. Ex: f3.exibeDados(); Se o método não é void, sua chamada deve estar dentro de alguma instrução que saiba fazer algo com aquele valor. Ex: System.out.println("Nome do funcionário: " + f3.getNome()); Programação I - Prof. Aníbal - Notas de aula 2 9 Entrada de dados Vamos fazer uma classe de teste para a classe Funcionario, mais flexível, que permitirá ao usuário entrar com alguns dados de um funcionário via teclado. Para tanto, vamos utilizar uma outra classe (feita por este professor) que possui métodos adequados para a entrada de dados via teclado. A classe tem nome Teclado e tem três métodos, sem parâmetros, cujas declarações (assinaturas) são: public int leInt() // retorna um inteiro obtido via teclado public double leDouble() // retorna um double obtido via teclado public String leString() // retorna um String obtido via teclado Observe que não são métodos void, pois retornam um valor do tipo indicado (int, no primeiro método, double, no segundo, e String, no terceiro). Assim, a chamada produz um valor do tipo correspondente, com o qual devemos fazer algo como uma atribuição, ou mandar imprimir, ou envolver num cálculo, etc. Ex: Apresentamos uma classe de teste alternativa para a classe Funcionario, que permite obter do teclado o nome, o salário e a quantidade de dependentes, que depois serão passados como argumentos para o construtor que tem a assinatura public Funcionario(String n, double sal, int nd) public class TestaFuncionario{ public static void main (String args[]){ Teclado t = new Teclado(); // instancia um objeto do tipo Teclado System.out.println("Informe o nome: "); String nom = t.leString(); System.out.println("Digite o salário: "); double sal = t.leDouble(); System.out.println("Digite o número de dependentes: "); int numDep = t.leInt(); Funcionario f1 = new Funcionario(nom, sal, numDep); f1.exibeDados(); } } Exercício 2.16. Escreva um método para a classe Carro que permita mudar o consumo médio a partir de um valor digitado pelo usuário no teclado. Entrada de dados com mensagem A classe Teclado foi dotada de três outros métodos, sobrecarregando cada um dos três apresentados antes, contendo um parâmetro que permite passar a mensagem a ser impressa para orientar o usuário: public int leInt(String msg) // retorna um inteiro obtido via teclado public double leDouble(String msg) // retorna um double obtido via teclado public String leString(String msg) // retorna um String obtido via teclado Ex. A classe de teste do exemplo anterior poderia ser escrita sem usar os System.out.println e ter o mesmo efeito. Veja: Programação I - Prof. Aníbal - Notas de aula 2 10 public class TestaFuncionario{ public static void main (String args[]){ Teclado t = new Teclado(); String nom = t.leString("Informe o nome: "); double sal = t.leDouble("Digite o salário: "); int numDep = t.leInt("Digite o número de dependentes: "); Funcionario f1 = new Funcionario(nom, sal, numDep); f1.exibeDados(); } } Ou, ainda, de uma forma mais simplificada, evitando o uso das três variáveis locais* nom, sal e numDep: public class TestaFuncionario{ public static void main (String args[]){ Teclado t = new Teclado(); new Funcionario(t.leString("Informe o nome: "), t.leDouble("Digite o salário: "), t.leInt("Digite o número de dependentes: ")).exibeDados(); } } Este último exemplo mostra que a chamada de um método pode ser um argumento. Repare, também, que dispensamos a variável objeto f1. Tente explicar a consequência disto. (*)Variáveis locais serão explanadas com mais detalhes em capítulo futuro A classe Scanner Java possui a classe Scanner que tem a mesma função de nossa classe Teclado e pode ser pesquisada pelo aluno na Biblioteca Java ou na bibliografia. Preferimos usar a classe Teclado por sua maior simplicidade. Programação I - Prof. Aníbal - Notas de aula 2 11