Методы

**Методы** — некие "строительные блоки" программы. Они помогают убирать повторения одних и тех же участков кода.

## Методы — показываем на примере

Вы, наверняка, ещё не поняли, что это такое. Объясним на примере. В Java есть встроенный класс `Math`, который предоставляет множество методов для чисел. Например, мы хотим извлечь квадратный корень из 9. Тогда мы просто вызываем этот метод, и он возвращает значение:

```
int root = Math.sqrt(9);
 ^ ^
 Класс Метод
//Теперь root = 3

```
Ещё один пример:

```
//Допустим, что вы создаёте программу, которая работает с базой данных,
//содержащей данные о работниках компании.

//Например, этот код добавляет в базу нового работника:

Database db = new Database();
db.add("Дмитрий Иванов");
db.update();

//Вместо того, чтобы каждый раз дублировать эти строки, давайте запихнём
//их в метод под названием newWorker(String name)

public void newWorker(String name) {
 Database db = new Database();
 db.add("Дмитрий Иванов");
 db.update();
}

//Теперь для добавления нового работника вам вместо трёх строк достаточно написать одну:
newWorker("Алексей Павлов");

```

## Объявление методов

### Синтаксис

```
уровень\_доступа модификаторы тип\_возвращаемого\_значения имя\_метода (параметры\_через\_запятую\_необязательно) {
 тело метода
}

```

* **Уровень доступа:** если Вы ещё не знакомы с ними, ставьте `public`.
* **Модфикаторы:** Если вы ещё не знакомы с ними — пропустите, они необязательны.
* **Тип возвращаемого значения:** если Ваш метод не должен ничего возвращать, ставьте `void`.
* **Имя метода:** любое имя, ограничения такие же, как и у переменных. Пишите с маленькой буквы!
* **Тело метода:** код, который будет выполняться при вызове метода.

### Пример

Создадим метод, который просто выводит строку "Это прекрасный метод!" на экран.

```
public void printText() {
 System.out.println("Это прекрасный метод!");
}

```
Этот метод открытый (public), ничего не возвращает (void) и не принимает никаких параметров (в круглых скобках ничего нет).

## Вызов методов

Вызвать метод очень просто. Когда Вы его вызовете, он выполнится, после чего выполнение кода пойдёт к инструкциям, следующим после **вызова** метода.

**ПРИМЕЧАНИЕ.** Если вы вызываете другие методы напрямую из `main()`, то вам нужно перед типом возвращаемого значения добавить `static`, т.к. `main()` является статическим методом.

```
//Допустим, у нас есть метод test()
//И класс Test, содержащий метод test()

test(); //Если он в текущем классе
Test testObj = new Test(); //Если он в другом классе, создаём объект этого класса
testObj.test(); //И потом вызываем

Test.test(); //Если метод в другом классе и он (метод) статический

```

## Принятие параметров методом

Методы были бы довольно бесполезны, если бы они не могли принимать параметры. При создании метода добавьте в скобки параметры (их количество неограниченно):

### Синтаксис

```
имя\_метода(тип\_параметра\_1 имя\_переменной\_1, тип\_параметра\_2 имя\_переменной\_2)

```

### Пример

```
//Метод складывает 2 числа и выводит на экран результат

public void add(int num1, int num2) {

 int result = num1 + num2;
 System.out.println(Integer.valueOf(result));

}

//Вызывать метод будем так:
add(8, 32);

```

## Возврат значения из метода

Вышеназванный метод `add()` был бы гораздо более полезным, если бы он возвращал сумму двух чисел.

### Синтаксис

```
return значение

```

### Пример

Допишем метод `add()`.

```
//Метод складывает 2 числа и возвращает результат

public int add(int num1, int num2) {

 return num1 + num2;

}

//Вызовем метод и используем возвращаемое значение.
//Оно будет подставлено в выражение вместо вызова метода.
int sum = add(8, 12);
//Теперь sum = 20

```
**ОБРАТИТЕ ВНИМАНИЕ.** Раз этот метод возвращает значение типа `int`, я в сигнатуре заменил `void` на `int`.

## Как ведут себя переменные внутри методов

Переменная, объявленная в методе, называется *локальной*, и доступна только из этого же метода. Но существуют также и *глобальные* переменные, которые доступны во всех методах текущего класса. Чтобы объявить глобальную переменную, просто сделайте это внутри класса, но вне какого-либо метода.

```
public class Main {

 String globalStr = "Эта строка доступна отовсюду";

 public static void main(String[] args) {
 int digit;
 digit = 0; //Всё ок
 globalStr = "Всё ок";
 }

 public int add(int num1, int num2) {

 digit = num1 + num2; //ОШИБКА! Эта переменная из другого метода!
 globalStr = "Всё тоже ок";
 return num1 + num2;

}

}

```
**ОБРАТИТЕ ВНИМАНИЕ.** Если у вас есть две переменные с одним названием, но одна локальная, а другая глобальная, то, чтобы обратиться к локальной, обращайтесь к ней как к обычной переменной. Но, чтобы обратиться к глобальной переменной, надо использовать ключевое слово `this`:

```
this.имя\_глобальной\_переменной

```

## Переменное количество параметров

Метод также может принимать переменное количество параметров. Такой синтаксис очень удобен, даже несмотря на то, что Вы можете передавать массивы в метод. Итак, чтобы указать, что метод принимает переменное количество параметров, поставьте после типа многоточие. **Важное замечание:** переменное количество параметров должно укзаываться **в конце** метода:

```
//(x - имя метода)

x(int ...nums, String text); //Так нельзя! Переменный параметр должен быть в конце!
x(String text, int ...nums) //А вот так можно

```

Давайте теперь ещё допишем `add()`, чтобы он мог складывать любое количество чисел!

```
//Метод складывает числа и возвращает их сумму

public int add(int... nums) {

 int result = 0;
 //А вот и практическое применение циклов: перебор массивов.
 //А т.к. переменный параметр работает так же как массив, мы его тоже можем перебрать
 for (int i = 0; i != nums.length; i++) {
 //На каждой итерации прибавляем следующее число
 result += nums[i];
 }

 return result;

}

}

```
**ПРИМЕЧАНИЕ.** У переменного параметра, в отличии от массива, length возвращает не количество элементов, а последний индекс.

## Перегрузка методов

Рассмотрим следующий пример. У нас есть метод `sort()`, который сортирует целые числа по возрастанию. Но мы также хотим сделать метод для сортировки вещественных чисел. Неужели нужно создавать отдельно метод `sortInt()` и `sortFloat()`? Нет. Для этого есть **перегрузка методов**. Благодаря ей, можно создавать два метода с одинаковым названием, но при условии, что они будут принимать разные параметры. Метод может различаться типом и/или порядком параметров.

**ПРИМЕЧАНИЕ.** Если вам вдруг понадобится отсортировать массив, то в Java есть для этого отдельный метод! Не изобретайте велосипед.

```
public void sort(int[]) {

}

public void sort(float[]) {

}

//Вызывать метод так:
int[] nums = {0, 8, 73, 643, 3, 89, 90, 12};
sort(nums);
//Или так, для вещ. чисел:
float[] floatNums = (1.5, 56.7, 32.9, 23.0, 404.4, 897.1);
sort(floatNums);

```