— Привет, Амиго! Надеюсь, тебе понравилось решать задачи с помощью собственных методов, и ты понял, насколько это удобно. А теперь поговорим о самом интересном.

— Интригуешь, Диего… Новая тема?

— Каждая тема — новая, юный робот! И эта — не исключение. Хоть и снова о методах. Ты уже, наверное, заметил по методам типа System.out.println(), что в методы можно передавать параметры.

— Параметры — это то, что пишется в скобках?

— Да, именно так. И, собственно говоря, параметры очень сильно повышают пользу от создания и использования методов.

— Про использование я понял и, получается, уже делал. А как нам объявить метод с параметрами?

— На самом деле сделать это довольно просто:

public static void имя(параметры)
{
   код метода
}

— Где имя — это уникальное имя метода, а код метода — это команды, из которых состоит метод. А параметры — это параметры метода, перечисленные через запятую.

— Ммм...Кажется, понял… Или нет…

— Давай-ка лучше я детальнее распишу этот шаблон, чтобы ты точно понял, что ты — понял:

public static void имя(тип1 имя1, тип2 имя2, тип3 имя3)
{
   код метода
}

Вот примеры:

Код Пояснение
public static void print(String str)
{
}
Объявлен метод print с параметром
String str
public static void print(String str, int count)
{
}
Объявлен метод print с двумя параметрами
String str
int count
public static void write(int x, int y)
{
}
Объявлен метод write с двумя параметрами
int x
int y

— Ага… Теперь ясно. Ну а если мы не хотим, чтобы у метода были параметры, просто оставляем круглые скобки пустыми.

— Именно так. По сути, параметры — это специальные переменные метода. С их помощью в метод можно передавать различные значения при его вызове. Ну а если передавать значения не нужно, то оставляем скобки пустыми.

— Давай, например, напишем метод, который выводит на экран заданную строку текста какое-то заданное количество раз. Есть соображения, как это нужно делать?

— Так... Как написать код по выводу строки на экран несколько раз, я вроде бы в курсе...

— А как задать строку, которую нужно вывести? И как задать количество выводов? Догадываешься уже?

— Что-то начинает проясняться… Наверное с помощью параметров метода?

— Именно. Параметр “строка” и числовой параметр “количество выводов”. Вот как будет выглядеть код этой задачи:

Код Пояснение
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.println(text);
   }

   public static void main(String[] args)
   {
     printLines("Привет", 10);
     printLines("Пока", 20);
   }
}

Объявили метод printLines с параметрами:
String text, int count

Метод выводит на экран count раз строку text



Вызываем метод printLines с разными параметрами

— Каждый раз при вызове метода его переменным-параметрам присваиваются переданные значения, и только потом начинают выполняться команды внутри метода.

Аргументы метода

— Хочу, чтобы ты обратил особое внимание на вызов метода с параметрами. Те значения, которые передаются в метод, при его вызове принято называть аргументами метода.

Давай ещё раз посмотрим на наш пример:

Код Пояснение
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.println(text);
   }

   public static void main(String[] args)
   {
     printLines("Привет", 10);
     printLines("Пока", 20);
   }
}

Объявили метод printLines с параметрами:
String text, int count

Метод выводит на экран count раз строку text


Вызываем метод printLines с параметрами
text = "Привет"; count = 10;
text = "Пока"; count = 20;

— Когда метод printLines вызвался в первый раз, его переменным-параметрам были присвоены такие значения:

String text = "Привет", int count = 10.

— Когда метод printLines вызвался во второй раз, его переменным-параметрам были присвоены другие значения:

String text = "Пока", int count = 20.

— Параметры метода — это именно переменные, которым присваиваются определенные значения при вызове метода. Сами же значения "Привет", "Пока", 10 и 20 называются аргументами метода.

— Постараюсь запомнить разницу и не путать эти понятия.

Конфликт имен переменных при вызове метода

— Когда ты вызываешь метод, то в качестве аргументов можешь использовать переменные.

— Это вроде как логично!

— Логично-то логично, но потенциально может нести некоторые сложности. Вернёмся ещё раз к нашему примеру, но вынесем аргументы в отдельные переменные:

Код Пояснение
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.print(text);
   }

   public static void main(String[] args)
   {
     String str = "Привет";
     int n = 10;
     printLines(str, n);
   }
}

Объявили метод printLines с параметрами:
String text, int count

Метод выводит на экран count раз строку text



Вызываем метод printLines с параметрами:
text = str;
count = n;

— Хм… Не вижу никаких сложностей. У нас есть переменная str, ее значение присваивается переменной text при вызове метода. У нас есть переменная n, ее значение присваивается переменной count при вызове метода. Пока все понятно.

— Хорошо-хорошо. А теперь давай переименуем наши переменные в методе main:

Код Пояснение
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.print(text);
   }

   public static void main(String[] args)
   {
     String text = "Привет";
     int count = 10;
     printLines(text, count);
   }
}

Объявили метод printLines с параметрами:
String text, int count

Метод выводит на экран count раз строку text



Вызываем метод printLines с параметрами:
text = text;
count = count;

— Обрати внимание на две вещи

Первое: у нас есть переменные с одинаковыми именами в разных методах. Это разные переменные (мы их специально раскрасили в разные цвета). Все работает так же, как и в предыдущем примере, когда переменные в методе main назывались str и n.

Второе: при вызове метода никакого волшебства не происходит. Переменным-параметрам просто присваиваются значения аргументов. Независимо от того, это конкретные числа, строки, переменные или выражения.

— После переименования переменных в методе main ничего не поменялось. Это как были разные переменные в разных методах, так и остались. Никакой магической связи между переменными text и text нет.

— Буду знать.

undefined
7
Задача
Java Syntax Pro, 7 уровень, 2 лекция
Недоступна
Любимое блюдо
Переименуй параметры метода printPersonInfo(): - firstName в name; - lastName в surname; - favoriteDish в meal; таким образом, чтобы функционал программы остался неизменным. Имена переменных в методе main() оставь без изменений.
undefined
7
Задача
Java Syntax Pro, 7 уровень, 2 лекция
Недоступна
Ливерпульская четверка
Метод createCrew() выводит должности и имена членов экипажа космического корабля. Во избежание путаницы внутри метода, измени имена параметров createCrew(), чтобы они соответствовали именам переменных, которые передаются в метод: - name1 в navigator - name2 в pilot - name3 в secondPilot - name4 в fl

Передача ссылок в методы

— Надеюсь, ты уже усвоил всё, что я тебе раньше рассказывал о передаче аргументов в методы. Потому что сейчас мы погрузимся в эту тему чуть глубже. Слушай внимательно.

— Ты уже в курсе, что некоторые переменные в Java хранят не сами значения, а адреc (ссылку) блока памяти, где эти значения находятся. Так, например работают переменные-строки или переменные-массивы.

— Когда разработчик присваивает переменной-массиву другую переменную-массив, что происходит?

— Они начинают ссылаться на один и тот же адрес?

— Правильно. Две переменные начинают ссылаться на один и тот же контейнер в памяти:

— А что произойдет, если одна из этих переменных будет переменной-параметром метода?

Код Пояснение
class Solution
{
   public static void printArraySum(int[] data)
   {
     int sum = 0;
     for (int i = 0; i < data.length; i++)
       sum = sum + data[i];
     System.out.println(sum);
   }
   
   public static void main(String[] args)
   {
     int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30};
     printArraySum(months);
   }
}


Метод printArraySum считает сумму чисел переданного массива и выводит ее на экран

— Произойдет ровно то же самое: переменная-параметр data будет содержать ссылку на тот же контейнер, что и переменная months. При вызове метода просто произойдет присваивание data = months.

— А раз обе переменные ссылаются на один и тот же контейнер целых чисел, то метод printArraySum может не просто читать значения из массива, но и менять их!

— Кажется понял, но нужны ещё примеры!

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

Код Пояснение
class Solution
{
   public static void fill(int[][] data, int value)
   {
     for (int i = 0; i < data.length; i++)
     {
       for (int j = 0; j < data[i].length; j++)
         data[i][j] = value;
     }
  }

   public static void main(String[] args)
   {
     int[][] months = {{31, 28}, {31, 30, 31}, {30, 31, 31}};
     fill (months, 8);
   }
}


Метод fill проходится по всем ячейкам переданного двумерного массива и присваивает им значение value.






Создаем двумерный массив.
Заполняем весь массив числом 8.
undefined
7
Задача
Java Syntax Pro, 7 уровень, 2 лекция
Недоступна
Правильный порядок
Напишем утилиту для работы с массивами. Основная часть функционала готова: метод printArray() выводит в консоли все элементы массива. Тебе осталась мелочь: реализовать метод reverseArray(). Он должен менять порядок элементов массива на обратный. Метод должен работать только с массивами целочисленных

Методы с одинаковыми именами

— А теперь еще раз вернемся к именам методов.

— Не представляю, что ещё можно сказать об именах!

— Например, то, что стандарты языка Java требуют, чтобы у всех методов внутри одного класса были уникальные имена.

— То есть невозможно объявить в одном классе два одинаковых метода?

— А теперь — будь внимателен! Два одинаковых имени у метода в одном классе вполне могут быть! Но у них должны быть в таком случае разные параметры. То есть при сравнении методов на одинаковость учитываются не только имена, но и типы параметров! Именно типы, имена переменных-параметров не учитываются. Примеры:

Код Пояснение
void fill(int[] data, int value) {
}
void fill(int[][] data, int value) {
}
void fill(int[][][] data, int value)  {
}
Эти три метода считаются разными. Их можно объявить в одном классе.
void print(String str) {
}
void print(String str, String str2) {
}
void print(int val) {
}
void print(double val) {
}
void print() {
}
Все эти пять методов считаются разными. Их можно объявить в одном классе.
void sum(int x, int y) {
}
void sum(int data, int value) {
}
Эти два метода считаются одинаковыми (их нельзя объявить в одном классе).

— Ничего не понял! Зачем это всё? Почему одни методы считаются одинаковыми, а другие — разными? И почему не учитываются имена переменных-параметров при определении уникальности метода? Зачем вообще нужна уникальность?

— Дело в том, что когда компилятор компилирует программу, он должен точно знать, какую именно функцию и какой именно метод ты вызываешь в определенном месте.

— Например ты пишешь System.out.println("Привет") Компилятор умный, и он легко сделает вывод, что тут вызывается метод println() с параметром типа String. А если ты напишешь System.out.println(1.0), компилятор увидит тут вызов метода println() с параметром типа double. Он понятия не имеет, какое имя программист дал переменной при определении метода.

— Ааа, кажется, начинает доходить!

— Компилятор следит, чтобы при вызове метода типы аргументов и параметров совпадали, а на имя аргумента не обращает никакого внимания. В Java имена переменных-параметров никак не помогают компилятору определить вызываемый метод. Они нужны программисту, а не компилятору.

— Поэтому и не учитываются при определении уникальности метода?

— Да, всё правильно. Имя метода и типы его параметров называются сигнатурой метода. Пример: sum(int, int)

— Получается, каждый класс должен иметь не методы с уникальными именами, а методы с уникальными сигнатурами.

— Молодец, Амиго, ты отлично подытожил эту лекцию. Если что-то осталось непонятным, не дрейфь. Эта тема становится понятной после пары-тройки задач.

undefined
7
Задача
Java Syntax Pro, 7 уровень, 2 лекция
Недоступна
Универсальный солдат
Неплохо было бы иметь один метод для решения различных задач. У тебя есть возможность написать такой. Создай еще 9 методов universalMethod(). В сумме их должно получиться 10. Параметры, которые они должны принимать, придумай сам.