— Привет, Амиго! Надеюсь, тебе понравилось решать задачи с помощью собственных методов, и ты понял, насколько это удобно. А теперь поговорим о самом интересном.
— Интригуешь, Диего… Новая тема?
— Каждая тема — новая, юный робот! И эта — не исключение. Хоть и снова о методах. Ты уже, наверное, заметил по методам типа System.out.println()
, что в методы можно передавать параметры.
— Параметры — это то, что пишется в скобках?
— Да, именно так. И, собственно говоря, параметры очень сильно повышают пользу от создания и использования методов.
— Про использование я понял и, получается, уже делал. А как нам объявить метод с параметрами?
— На самом деле сделать это довольно просто:
public static void имя(параметры)
{
код метода
}
— Где имя
— это уникальное имя метода, а код метода
— это команды, из которых состоит метод. А параметры
— это параметры метода, перечисленные через запятую.
— Ммм...Кажется, понял… Или нет…
— Давай-ка лучше я детальнее распишу этот шаблон, чтобы ты точно понял, что ты — понял:
public static void имя(тип1 имя1, тип2 имя2, тип3 имя3)
{
код метода
}
Вот примеры:
Код | Пояснение |
---|---|
|
Объявлен метод print с параметромString str |
|
Объявлен метод print с двумя параметрамиString str int count
|
|
Объявлен метод write с двумя параметрамиint x int y |
— Ага… Теперь ясно. Ну а если мы не хотим, чтобы у метода были параметры, просто оставляем круглые скобки пустыми.
— Именно так. По сути, параметры — это специальные переменные метода. С их помощью в метод можно передавать различные значения при его вызове. Ну а если передавать значения не нужно, то оставляем скобки пустыми.
— Давай, например, напишем метод, который выводит на экран заданную строку текста какое-то заданное количество раз. Есть соображения, как это нужно делать?
— Так... Как написать код по выводу строки на экран несколько раз, я вроде бы в курсе...
— А как задать строку, которую нужно вывести? И как задать количество выводов? Догадываешься уже?
— Что-то начинает проясняться… Наверное с помощью параметров метода?
— Именно. Параметр “строка” и числовой параметр “количество выводов”. Вот как будет выглядеть код этой задачи:
Код | Пояснение |
---|---|
|
Объявили метод printLines с параметрами:String text , int count Метод выводит на экран count раз строку text Вызываем метод printLines с разными параметрами |
— Каждый раз при вызове метода его переменным-параметрам присваиваются переданные значения, и только потом начинают выполняться команды внутри метода.
Аргументы метода
— Хочу, чтобы ты обратил особое внимание на вызов метода с параметрами. Те значения, которые передаются в метод, при его вызове принято называть аргументами метода.
Давай ещё раз посмотрим на наш пример:
Код | Пояснение |
---|---|
|
Объявили метод 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
называются аргументами метода.
— Постараюсь запомнить разницу и не путать эти понятия.
Конфликт имен переменных при вызове метода
— Когда ты вызываешь метод, то в качестве аргументов можешь использовать переменные.
— Это вроде как логично!
— Логично-то логично, но потенциально может нести некоторые сложности. Вернёмся ещё раз к нашему примеру, но вынесем аргументы в отдельные переменные:
Код | Пояснение |
---|---|
|
Объявили метод printLines с параметрами:String text , int count Метод выводит на экран count раз строку text Вызываем метод printLines с параметрами:text = str; count = n;
|
— Хм… Не вижу никаких сложностей. У нас есть переменная str
, ее значение присваивается переменной text
при вызове метода. У нас есть переменная n
, ее значение присваивается переменной count
при вызове метода. Пока все понятно.
— Хорошо-хорошо. А теперь давай переименуем наши переменные в методе main
:
Код | Пояснение |
---|---|
|
Объявили метод printLines с параметрами:String text , int count Метод выводит на экран count раз строку text Вызываем метод printLines с параметрами:text = text; count = count; |
— Обрати внимание на две вещи
Первое: у нас есть переменные с одинаковыми именами в разных методах. Это разные переменные (мы их специально раскрасили в разные цвета). Все работает так же, как и в предыдущем примере, когда переменные в методе main
назывались str
и n
.
Второе: при вызове метода никакого волшебства не происходит. Переменным-параметрам просто присваиваются значения аргументов. Независимо от того, это конкретные числа, строки, переменные или выражения.
— После переименования переменных в методе main ничего не поменялось. Это как были разные переменные в разных методах, так и остались. Никакой магической связи между переменными text
и text
нет.
— Буду знать.
Передача ссылок в методы
— Надеюсь, ты уже усвоил всё, что я тебе раньше рассказывал о передаче аргументов в методы. Потому что сейчас мы погрузимся в эту тему чуть глубже. Слушай внимательно.
— Ты уже в курсе, что некоторые переменные в Java хранят не сами значения, а адреc (ссылку) блока памяти, где эти значения находятся. Так, например работают переменные-строки или переменные-массивы.
— Когда разработчик присваивает переменной-массиву другую переменную-массив, что происходит?
— Они начинают ссылаться на один и тот же адрес?
— Правильно. Две переменные начинают ссылаться на один и тот же контейнер в памяти:
— А что произойдет, если одна из этих переменных будет переменной-параметром метода?
Код | Пояснение |
---|---|
|
Метод printArraySum считает сумму чисел переданного массива и выводит ее на экран |
— Произойдет ровно то же самое: переменная-параметр data
будет содержать ссылку на тот же контейнер, что и переменная months
. При вызове метода просто произойдет присваивание data = months
.
— А раз обе переменные ссылаются на один и тот же контейнер целых чисел, то метод printArraySum
может не просто читать значения из массива, но и менять их!
— Кажется понял, но нужны ещё примеры!
— Ну, например, мы можем написать свой собственный метод, который заполняет двумерный массив одинаковыми значениями. Вот как он мог бы выглядеть:
Код | Пояснение |
---|---|
|
Метод fill проходится по всем ячейкам переданного двумерного массива и присваивает им значение value .Создаем двумерный массив. Заполняем весь массив числом 8 . |
Методы с одинаковыми именами
— А теперь еще раз вернемся к именам методов.
— Не представляю, что ещё можно сказать об именах!
— Например, то, что стандарты языка Java требуют, чтобы у всех методов внутри одного класса были уникальные имена.
— То есть невозможно объявить в одном классе два одинаковых метода?
— А теперь — будь внимателен! Два одинаковых имени у метода в одном классе вполне могут быть! Но у них должны быть в таком случае разные параметры. То есть при сравнении методов на одинаковость учитываются не только имена, но и типы параметров! Именно типы, имена переменных-параметров не учитываются. Примеры:
Код | Пояснение |
---|---|
|
Эти три метода считаются разными. Их можно объявить в одном классе. |
|
Все эти пять методов считаются разными. Их можно объявить в одном классе. |
|
Эти два метода считаются одинаковыми (их нельзя объявить в одном классе). |
— Ничего не понял! Зачем это всё? Почему одни методы считаются одинаковыми, а другие — разными? И почему не учитываются имена переменных-параметров при определении уникальности метода? Зачем вообще нужна уникальность?
— Дело в том, что когда компилятор компилирует программу, он должен точно знать, какую именно функцию и какой именно метод ты вызываешь в определенном месте.
— Например ты пишешь System.out.println("Привет")
Компилятор умный, и он легко сделает вывод, что тут вызывается метод println()
с параметром типа String
. А если ты напишешь System.out.println(1.0)
, компилятор увидит тут вызов метода println()
с параметром типа double
. Он понятия не имеет, какое имя программист дал переменной при определении метода.
— Ааа, кажется, начинает доходить!
— Компилятор следит, чтобы при вызове метода типы аргументов и параметров совпадали, а на имя аргумента не обращает никакого внимания. В Java имена переменных-параметров никак не помогают компилятору определить вызываемый метод. Они нужны программисту, а не компилятору.
— Поэтому и не учитываются при определении уникальности метода?
— Да, всё правильно. Имя метода и типы его параметров называются сигнатурой метода. Пример: sum(int, int)
— Получается, каждый класс должен иметь не методы с уникальными именами, а методы с уникальными сигнатурами.
— Молодец, Амиго, ты отлично подытожил эту лекцию. Если что-то осталось непонятным, не дрейфь. Эта тема становится понятной после пары-тройки задач.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ