CodeGym /Blogue Java /Random-PT /Declaração de método
John Squirrels
Nível 41
San Francisco

Declaração de método

Publicado no grupo Random-PT
Oi! Você já sabe como criar suas próprias classes com campos e métodos. Agora vamos nos deter nos métodos.
Declaração de método - 1
É claro que já fizemos isso mais de uma vez em nossas aulas, mas tratamos principalmente de generalidades. Hoje, vamos dissecar métodos e estudar de que são feitos, as várias maneiras de criá-los e como gerenciar tudo isso. :) Vamos!

Declaração de método

Todo o código que define um método é chamado de declaração de método . A forma geral de uma declaração de método pode ser descrita da seguinte forma:

access modifier, return type, method name (parameter list) {
    // method body
}
Como exemplos, dê uma olhada nas declarações dos vários métodos da Dogclasse.

public class Dog {

   String name;

   public Dog(String name) {
       this.name = name;
   }

   public static void main(String[] args) {
       Dog max = new Dog("Max");
       max.woof();

   }

   public void woof() {
       System.out.println("A dog named " + name + " says \"Woof, woof!\"");
   }

   public void run(int distanceInFeet) {
       System.out.println("A dog named " + name + " ran " + distanceInFeet + " feet!");
   }

   public String getName() {
       return name;
   }
}

1. Modificador de acesso

O modificador de acesso é sempre indicado primeiro. Todos os Dogmétodos da classe são marcados com o modificador público . Isso significa que podemos chamá-los de qualquer outra classe:

public class Main {

   public static void main(String[] args) {

       Dog butch = new Dog("Butch");
       butch.run(100);
   }

}
Como você pode ver, os Dogmétodos da classe são facilmente acessados ​​na Mainclasse. Isso é possível devido ao modificador público . Em Java, existem outros modificadores. Nem todas permitem que métodos sejam usados ​​em outras classes. Falaremos sobre eles em outras lições. A principal coisa a lembrar é o que o modificador é responsável: se um método é acessível em outras classes :)

2. palavra-chave estática

Um dos Dogmétodos, main(), é marcado com a palavra-chave static . Também faz parte da declaração do método e já sabemos o seu significado. Não o mencionamos no modelo de declaração de método fornecido no início da lição, porque é opcional. Se for especificado, deve vir após o modificador de acesso. Lembra que nas últimas aulas falamos sobre variáveis ​​estáticas (de classe)? Quando aplicada a métodos, esta palavra-chave tem aproximadamente o mesmo significado. Se um método for static , ele poderá ser usado sem uma referência a um objeto específico da classe. E, de fato, você não precisa de um Dogobjeto para executar o main()método estático noDogaula. Ele vai funcionar muito bem sem um. Se esse método não fosse estático, primeiro precisaríamos criar um objeto para executá-lo.

3. Valor de retorno

Se nosso método deve retornar algo, especificamos o tipo do valor de retorno. Isso fica evidente no exemplo do getName()getter:

public String getName() {
   return name;
}
Ele retorna um Stringobjeto. Se um método não retornar nada, a palavra-chave void será usada, como no woof()método:

public void woof() {
   System.out.println("A dog named " + name + " says \"Woof, woof!\"");
}

Métodos com o mesmo nome

Existem situações em que queremos várias maneiras diferentes de chamar um método. Por que não criar nossa própria inteligência artificial? Amazon tem Alexa, Apple tem Siri, então por que não deveríamos ter um? :) No filme Homem de Ferro, Tony Stark cria sua própria inteligência artificial incrível, Jarvis. Vamos prestar homenagem a esse personagem incrível e nomear nossa IA em sua homenagem. :) A primeira coisa que precisamos fazer é ensinar Jarvis a dizer olá para as pessoas que entram na sala (seria estranho se um intelecto tão incrível se revelasse indelicado).

public class Jarvis {

   public void sayHi(String name) {
       System.out.println("Good evening, " + name + ". How are you?");
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
   }
}
Saída do console: Boa noite, Tony Stark. Como vai você? Muito bom! Jarvis agora pode receber convidados. Claro, com mais frequência do que seu mestre, Tony Stark. Mas e se ele não vier sozinho! Mas nosso sayHi()método aceita apenas um argumento. E assim ele só pode cumprimentar uma pessoa entrando na sala e ignorará a outra. Não é muito educado, combinado? :/ Neste caso, podemos resolver o problema simplesmente escrevendo 2 métodos com o mesmo nome, mas parâmetros diferentes:

public class Jarvis {

   public void sayHi(String firstGuest) {
       System.out.println("Good evening, " + firstGuest + ". How are you?");
   }

   public void sayHi(String firstGuest, String secondGuest) {
       System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
   }

}
Isso é chamado de sobrecarga de método . A sobrecarga de métodos permite que nosso programa seja mais flexível e acomode várias formas de trabalho. Vamos rever como funciona:

public class Jarvis {

   public void sayHi(String firstGuest) {
       System.out.println("Good evening, " + firstGuest + ". How are you?");
   }

   public void sayHi(String firstGuest, String secondGuest) {
       System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
       jarvis.sayHi("Tony Stark", "Captain America");
   }
}
Saída do console: Boa noite, Tony Stark. Como vai você? Boa noite, Tony Stark e Capitão América. Como vai você? Excelente, ambas as versões funcionaram. :) Mas não resolvemos o problema! E se houver três convidados? Poderíamos, é claro, sobrecarregar o sayHi()método novamente, para que ele aceite três nomes de convidados. Mas podem ser 4 ou 5. Até o infinito. Não existe uma maneira melhor de ensinar Jarvis a lidar com qualquer número de nomes, sem sobrecarregar o sayHi()método um milhão de vezes ()? :/ Claro que tem! Se não houvesse, você acha que Java seria a linguagem de programação mais popular do mundo? ;)

public class Jarvis {

   public void sayHi(String...names) {

       for (String name: names) {
           System.out.println("Good evening, " + name + ". How are you?");
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
       System.out.println();
       jarvis.sayHi("Tony Stark", "Captain America");
   }
}
Quando ( String... nomes ) é usado como parâmetro, indica que uma coleção de Strings será passada para o método. Não precisamos especificar com antecedência quantos serão, então agora nosso método é muito mais flexível:

public class Jarvis {

   public void sayHi(String...names) {

       for (String name: names) {
           System.out.println("Good evening, " + name + ". How are you?");
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark", "Captain America", "Black Widow", "Hulk");
   }
}
Saída do console: Boa noite, Tony Stark. Como vai você? Boa noite, Capitão América. Como vai você? Boa noite Viúva Negra. Como vai você? Boa noite, Hulk. Como vai você? Dentro do método, iteramos sobre todos os argumentos e exibimos frases formatadas com nomes. Aqui usamos um for-eachloop simplificado (que você já viu antes). É perfeito aqui, porque a notação ( String... nomes ) na verdade significa que o compilador coloca todos os argumentos passados ​​em uma matriz. Como resultado, podemos trabalhar com nomes de variáveiscomo trabalharíamos com uma matriz, inclusive iterando por ela em um loop. Além disso, funcionará com qualquer número de strings passadas! Dois, dez, até mil - o método funcionará adequadamente com qualquer número de convidados. Muito mais conveniente do que sobrecarregar o método com todas as possibilidades, não acha? :) Aqui está outro exemplo de sobrecarga de método. Vamos dar um printInfoFromDatabase()método a Jarvis. Ele exibirá informações sobre uma pessoa de um banco de dados. Se o banco de dados indicar que uma pessoa é um super-herói ou supervilão, exibiremos essa informação:

public class Jarvis {

   public void printInfoFromDatabase (String bio) {

       System.out.println(bio);
   }

   public void printInfoFromDatabase(String bio, boolean isEvil, String nickname) {

       System.out.println(bio);
       if (!isEvil) {
           System.out.println("Also known as the superhero " + nickname);
       } else {
           System.out.println("Also known as the supervillain " + nickname);
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.printInfoFromDatabase("Laura Palmer. Date of birth: July 22, 1972. Twin Peaks, Washington");
       System.out.println();
       jarvis.printInfoFromDatabase("Max Eisenhardt. Height: 15.6 ft. Weight: 189 lbs. ", true, "Magneto");
   }
}
Produção: Laura Palmer. Data de nascimento: 22 de julho de 1972. Twin Peaks, Washington Max Eisenhardt. Altura: 15,6 pés. Peso: 189 libras. Também conhecido como o supervilão Magneto So, o comportamento do nosso método depende dos dados que passamos para ele. Aqui está outro ponto importante: a ordem dos argumentos é importante! Digamos que nosso método receba uma String e um número:

public class Person {

   public static void sayYourAge(String greeting, int age) {
       System.out.println(greeting + " " + age);
   }

   public static void main(String[] args) {

       sayYourAge("My age is ", 33);
       sayYourAge(33, "My age is "); // Error!
   }
}
Se o método Personda classe sayYourAge()recebe uma string e um número como entrada, então esta é a ordem em que esses argumentos devem ser passados ​​para o método! Se os passarmos em uma ordem diferente, o compilador gerará um erro e a pessoa não poderá dizer sua idade. A propósito, os construtores, que abordamos na última lição, também são métodos! Você também pode sobrecarregá-los (ou seja, criar vários construtores com diferentes conjuntos de parâmetros) e a ordem dos argumentos passados ​​também é fundamentalmente importante para eles. São métodos reais! :)

Como invocar métodos com parâmetros semelhantes

Como você sabe, nullé uma palavra-chave em Java. É muito importante entender que nullnão é um objeto nem um tipo de dados . Imagine que temos uma Personclasse e um introduce()método, que anunciam o nome e a idade da pessoa. Além disso, a idade pode ser passada como texto ou número.

public class Person {

   public void introduce(String name, String age) {
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, Integer age) {
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person alex = new Person();
       alex.introduce ("Alex", "twenty-one");

       Person mary = new Person();
       mary.introduce("Mary", 32);
   }
}
Já estamos familiarizados com sobrecarga, então sabemos que ambos os métodos se comportarão como deveriam: Meu nome é Alex. Minha idade é vinte e um anos. Meu nome é Mary. Minha idade é 32 anos. Mas o que acontecerá se passarmos nullcomo segundo parâmetro em vez de uma string ou um número?

public static void main(String[] args) {

   Person victor = new Person();
   victor.introduce("Victor", null);// Ambiguous method call!
}
Receberemos um erro de compilação! O que causa isso e o que exatamente é a "ambiguidade"? Na verdade, é tudo muito simples. O problema é que temos duas versões do método: uma com a Stringcomo segundo argumento e outra com a Integercomo segundo argumento. Mas a Stringe an Integerpodem ser ambos null! Por serem tipos de referência, nullé o valor padrão para ambos. É por isso que nessa situação o compilador não consegue descobrir qual versão do método deve chamar. A solução para este problema é bastante simples. Nullpode ser explicitamente convertido em um tipo de referência específico. Assim, ao chamar um método, você pode indicar entre parênteses o tipo de dado que deseja para o segundo argumento! O compilador entenderá sua "dica" e chamará o método correto:

public class Person {

   public void introduce(String name, String age) {
       System.out.println("Method with two strings!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, Integer age) {
       System.out.println("Method with a string and a number!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person victor = new Person();
       victor.introduce("Victor", (String) null);
   }
}
Saída: Método com duas strings! Meu nome é Vitor. My age is null Observe que, se o parâmetro number fosse um primitivo int, em vez de uma instância do tipo de referência Integer, não haveria esse erro.

public class Person {

   public void introduce(String name, String age) {
       System.out.println("Method with two strings!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, int age) {
       System.out.println("Method with a string and a number!!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person victor = new Person();
       victor.introduce("Victor", null);
   }
}
Você consegue adivinhar por quê? Se você adivinhou o porquê, muito bem! :) Porque os primitivos não podem ser null. Agora o compilador tem apenas uma escolha, ou seja, chamar o introduce()método com duas strings. Esta é a versão do método que será executada toda vez que o método for chamado.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION