JavaRush /Blogue Java /Random-PT /Assinatura do método

Assinatura do método

Publicado no grupo Random-PT
Olá! Você já dominou a criação de suas próprias classes, com campos e métodos. Hoje falaremos detalhadamente sobre os métodos. É claro que já fizemos isso mais de uma vez em nossas palestras, mas falamos principalmente sobre pontos gerais. Hoje analisaremos literalmente os métodos “em partes” - descobriremos em que consistem, quais opções existem para criá-los e como tudo isso pode ser gerenciado :) Vamos lá!Assinatura do método - 1

Assinatura do método

Todo código que descreve um método é chamado de declaração de método . Uma assinatura de método inclui o nome do método e os tipos de parâmetros em uma ordem específica. A aparência geral do anúncio pode ser descrita da seguinte forma:
модификатор доступа, тип возвращаемого значения, Name метода(список параметров) {
    // тело метода
}
Vejamos um exemplo de declarações de vários métodos da classe Dog.
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("Собака по имени " + name + " говорит \"Гав-гав!\"");
   }

   public void run(int meters) {
       System.out.println("Собака по имени " + name + " пробежала " + meters + " метров!");
   }

   public String getName() {
       return name;
   }
}

1. Modificador de acesso

O modificador de acesso é sempre listado primeiro. Todos os métodos de classe Dogsão designados pelo modificador public. Ou seja, podemos chamá-los de qualquer outra classe:
public class Main {

   public static void main(String[] args) {

       Dog butch = new Dog("Бутч");
       butch.run(100);
   }

}
Os métodos de classe Dog, como você pode ver, são facilmente acessíveis na classe Main. Isso é possível graças ao modificador public. Existem outros modificadores em Java, e nem todos permitirão que você use um método dentro de outra classe. Falaremos sobre eles em outras palestras. O principal é lembrar pelo que o modificador é responsável: a disponibilidade/inacessibilidade do método em outras classes :)

2. A palavra-chave estática

Um dos métodos Dog, ou seja, main()é indicado pela palavra-chave static. Se existir, deverá ser especificado após o modificador de acesso. Lembra que nas aulas anteriores falamos sobre variáveis ​​de classe estáticas? Quando aplicada a métodos, esta palavra tem aproximadamente o mesmo significado. Se um método for especificado como static, isso significa que ele pode ser usado sem referência a um objeto de classe específico. E, de fato, para executar um método estático main()em uma classe, Dogvocê não precisa criar uma instância Dog; ela é executada sem ela. Se este método não fosse estático, para usá-lo precisaríamos primeiro criar um objeto.

3. Valor de retorno.

Se nosso método deve retornar algo, então indicamos o tipo do valor de retorno. Isso pode ser visto no exemplo de um getter getName():
public String getName() {
   return name;
}
Ele retorna um objeto do tipo String. Se o método não retornar nada, a palavra-chave será especificada em vez do tipo void, como no método woof():
public void woof() {
   System.out.println("Собака по имени " + name + " говорит \"Гав-гав!\"");
}

Métodos com o mesmo nome

Existem situações em que nosso programa requer várias opções de funcionamento de um método. Por que não criamos nossa própria inteligência artificial? Amazon tem Alexa, Yandex tem Alice, então por que somos piores? :) No filme sobre o Homem de Ferro, Tony Stark criou sua própria inteligência artificial notável - JARVIS Vamos prestar homenagem ao personagem maravilhoso e nomear nossa IA em sua homenagem :) A primeira coisa que devemos ensinar a Jarvis é cumprimentar as pessoas que entram na sala (seria estranho se um intelecto tão grande se revelasse indelicado).
public class Jarvis {

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

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
   }
}
Saída do console:

Добрый вечер, Тони Старк, How ваши дела?
Ótimo! Jarvis sabe cumprimentar quem entra. Na maioria das vezes, é claro, será seu dono - Tony Stark. Mas ele pode não vir sozinho! E nosso método sayHi()recebe apenas um argumento como entrada. E, conseqüentemente, ele poderá cumprimentar apenas um dos que vierem e ignorará o outro. Não é muito educado, concorda?:/ Nesse caso, para resolver o problema, podemos simplesmente escrever 2 métodos na classe com o mesmo nome, mas com parâmetros diferentes:
public class Jarvis {

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

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

}
Isso é chamado de sobrecarga de método . A sobrecarga permite que nosso programa seja mais flexível e acomode diferentes opções de trabalho. Vamos verificar como funciona:
public class Jarvis {

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

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

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
       jarvis.sayHi("Tony Stark", "Captain America");
   }
}
Saída do console:

Добрый вечер, Тони Старк, How ваши дела? 
Добрый вечер, Тони Старк, Капитан Америка, How ваши дела?
Ótimo, ambas as opções funcionaram :) Porém, não resolvemos o problema! E se houver três convidados? Claro, podemos sobrecarregar o método novamente sayHi()para aceitar os nomes de três convidados. Mas pode haver 4 ou 5. E assim por diante, ad infinitum. Existe outra maneira de ensinar Jarvis a trabalhar com qualquer número de nomes, sem um milhão de sobrecargas de métodos sayHi()? :/ Claro que sim! Caso contrário, o 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 doing?");
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
       System.out.println();
       jarvis.sayHi("Tony Stark", "Captain America");
   }
}
O registro ( String...names) passado como parâmetro nos permite indicar que um determinado número de strings são passadas para o método. Não especificamos antecipadamente quantos deveriam ser, então a operação do nosso método agora se torna 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 doing?");
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark", "Captain America", "Black Widow", "Hulk");
   }
}
Saída do console:

Добрый вечер, Тони Старк, How ваши дела? 
Добрый вечер, Капитан Америка, How ваши дела? 
Добрый вечер, Черная Вдова, How ваши дела? 
Добрый вечер, Халк, How ваши дела?
Dentro do método, percorremos todos os argumentos e enviamos frases prontas com nomes para o console. Aqui usamos um loop simplificado for-each(você já o encontrou). É ótimo porque escrever String...namesna verdade significa que todos os parâmetros passados ​​são colocados em um array pelo compilador. Portanto, namesvocê pode trabalhar com uma variável como se fosse um array, incluindo fazer um loop através dela. Além disso, funcionará para qualquer número de linhas transferidas! Dois, dez e até mil - o método funcionará de forma confiável com qualquer número de convidados. Muito mais conveniente do que fazer sobrecargas para todas as opções possíveis, não concorda? :) Vamos dar outro exemplo de sobrecarga de métodos. Vamos adicionar um método ao Jarvis printInfoFromDatabase(). Ele imprimirá informações sobre a pessoa do banco de dados no console. Caso o banco de dados indique que uma pessoa é um super-herói ou supervilão, esta informação também será exibida na tela:
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("Также известен How супергерой " + nickname);
       } else {
           System.out.println("Также известен How суперзлодей " + nickname);
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.printInfoFromDatabase("Лора Палмер. Дата рождения - 22 июля 1972, город Твин Пикс, штат Washington");
       System.out.println();
       jarvis.printInfoFromDatabase("Макс Эйзенхарт. Рост 188см, вес 86 кг.", true, "Магнето");
   }
}
Conclusão:

Лора Палмер. Дата рождения - 22 июля 1972, город Твин Пикс, штат Washington
Макс Эйзенхарт. Рост 188см, вес 86 кг 
Также известен How суперзлодей Магнето
É assim que nosso método funciona dependendo dos dados que passamos para ele. Outro ponto importante:A ordem dos argumentos é importante! Digamos que nosso método receba uma string e um número como entrada:
public class Man {

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

   public static void main(String[] args) {

       sayYourAge("My age - ", 33);
       sayYourAge(33, "My age - "); //error!
   }
}
Se um método sayYourAge()de classe Manrecebe uma string e um número como entrada, então esta é a ordem em que eles precisam ser passados ​​no programa! Se os passarmos em uma ordem diferente, o compilador gerará um erro e a pessoa não conseguirá dizer sua idade. A propósito, os construtores que abordamos na aula passada também são métodos! Eles também podem estar sobrecarregados (criar vários construtores com diferentes conjuntos de argumentos) e para eles a ordem de passagem dos argumentos também é de fundamental importância. Métodos reais! :)

Como chamar métodos com parâmetros semelhantes

Como você sabe, em Java existe uma palavra nula. Ao trabalhar com ele, é muito importante entender que null não é um objeto nem um tipo de dado. Imagine que temos uma classe Man e um método introduce()que declara o nome e a idade de uma pessoa. Nesse caso, a idade pode ser transmitida na forma de texto ou expressa como um número.
public class Man {

   public void introduce(String name, String age) {
       System.out.println("Меня зовут " + name + ", мой возраст - " + age);
   }

   public void introduce(String name, Integer age) {
       System.out.println("Меня зовут " + name + ", мой возраст - " + age);
   }

   public static void main(String[] args) {

       Man sasha = new Man();
       sasha.introduce("Sasha", "двадцать один");

       Man masha = new Man();
       masha.introduce("Мария", 32);
   }
}
Já estamos familiarizados com sobrecarga, então sabemos que o método funcionará conforme o esperado nas duas vezes:

Меня зовут Саша, мой возраст - двадцать один 
Меня зовут Мария, мой возраст - 32 
Mas o que acontece se passarmos null como segundo parâmetro, não uma string ou um número?
public static void main(String[] args) {

   Man victor = new Man();
   victor.introduce("Виктор", null);//Ambiguous method call!
}
Teremos um erro de compilação! O erro “chamada de método ambíguo” é traduzido como “chamada de método ambíguo”. Por que isso poderia surgir e qual é a “ambiguidade”? Na verdade é simples. Acontece que temos duas variantes do método: with Stringe with Integercomo segundo argumento. Mas ambos Stringe Integerpodem ser nulos! Para ambos os tipos (já que são tipos de referência), null é o valor padrão. É por isso que o compilador nesta situação não consegue descobrir qual versão do método deve chamar. Resolver este problema é bastante simples. A questão é que null pode ser explicitamente convertido em um tipo de referência específico. Portanto, ao chamar um método, você pode indicar entre parênteses o tipo de dados necessário para o segundo argumento! O compilador entenderá sua “dica” e chamará o método necessário:
public class Man {

   public void introduce(String name, String age) {
       System.out.println("Метод с двумя строками!");
       System.out.println("Меня зовут " + name + ", мой возраст - " + age);
   }

   public void introduce(String name, Integer age) {
       System.out.println("Метод со строкой и числом!");
       System.out.println("Меня зовут " + name + ", мой возраст - " + age);
   }

   public static void main(String[] args) {

       Man victor = new Man();
       victor.introduce("Виктор", (String) null);
   }
}
Conclusão:

Метод с двумя строками! 
Меня зовут Виктор, мой возраст - null
Mas se o parâmetro numérico fosse um primitivo int, e não um objeto de tipo de referência Integer, tal erro não ocorreria.
public class Man {

   public void introduce(String name, String age) {
       System.out.println("Метод с двумя строками!");
       System.out.println("Меня зовут " + name + ", мой возраст - " + age);
   }

   public void introduce(String name, int age) {
       System.out.println("Метод со строкой и числом!!");
       System.out.println("Меня зовут " + name + ", мой возраст - " + age);
   }

   public static void main(String[] args) {

       Man victor = new Man();
       victor.introduce("Виктор", null);
   }
}
Você já adivinhou por quê? Se você adivinhou, muito bem :) Porque primitivos não podem ser iguais a nulos. Agora o compilador tem apenas uma opção para chamar o método introduce()- com duas linhas. É esta versão do método que será processada toda vez que o método for chamado.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION