1. Передача параметров
А теперь начинается самое интересное. Как вы уже, наверное, знаете, по методам типа 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 с разными параметрами
|
Каждый раз при вызове метода его переменным-параметрам присваиваются переданные значения, и только потом начинают выполняться команды внутри метода
2. Аргументы метода
Еще немного вашего внимания хочу обратить на вызов метода с параметрами.
Те значения, которые передаются в метод, при его вызове принято называть аргументами метода.
Давайте еще раз разберем пример:
Код | Пояснение |
---|---|
|
Объявили метод 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
называются аргументами метода.
3. Конфликт имен переменных при вызове метода
В качестве аргументов метода можно использовать переменные. Это просто и понятно, но потенциально может нести некоторые сложности. Рассмотрим тот же пример, но вынесем аргументы в отдельные переменные:
Код | Пояснение |
---|---|
|
Объявили метод 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
нет.
4. Передача ссылок в методы
Надеюсь, вы поняли все из предыдущей лекции, потому что сейчас мы снова затронем передачу аргументов в методы, только еще глубже.
Как вы уже знаете, некоторые переменные в Java хранят не сами значения, а адрес (ссылку) блока памяти, где эти значения находятся. Так, например работают переменные-строки или переменные-массивы.
Когда вы присваиваете переменной-массиву другую переменную-массив, что происходит? Правильно. Две переменные начинают ссылаться на один и тот же контейнер в памяти:
А что произойдет, если одна из этих переменных будет переменной-параметром метода?
Код | Пояснение |
---|---|
|
Метод printArraySum считает сумму чисел переданного массива и выводит ее на экран |
Произойдет ровно то же самое: переменная-параметр data
будет содержать ссылку на тот же контейнер, что и переменная months
. При вызове метода просто произойдет присваивание data = months
.
А раз обе переменные ссылаются на один и тот же контейнер целых чисел, то метод printArraySum
может не просто читать значения из массива, но и менять их!
Например, мы можем написать свой собственный метод, который заполняет двумерный массив одинаковыми значениями. Вот как он мог бы выглядеть:
Код | Пояснение |
---|---|
|
Метод fill проходится по всем ячейкам переданного двумерного массива и присваивает им значение value .Создаем двумерный массив. Заполняем весь массив числом 8 .
|
5. Методы с одинаковыми именами
А теперь еще раз вернемся к именам методов.
Стандарты Java требуют, чтобы у всех методов внутри одного класса были уникальные имена. Т.е. невозможно объявить в одном классе два одинаковых метода.
Только вот при сравнении методов на одинаковость учитываются не только имена, но и типы параметров! Причем имена переменных-параметров не учитываются. Примеры:
Код | Пояснение |
---|---|
|
Эти три метода считаются разными. Их можно объявить в одном классе. |
|
Все эти пять методов считаются разными. Их можно объявить в одном классе. |
|
Эти два метода считаются одинаковыми (их нельзя объявить в одном классе). |
Почему же одни методы считаются одинаковыми, а другие — разными? И почему не учитываются имена переменных-параметров при определении уникальности метода?
Зачем вообще нужна уникальность? Все дело в том, что когда компилятор компилирует вашу программу, он должен точно знать, какую именно функцию/метод вы вызываете в определенном месте.
Например вы пишете System.out.println("Привет")
Компилятор умный, и он легко сделает вывод, что тут вызывается метод println()
с параметром типа String
.
А если вы напишете System.out.println(1.0)
, компилятор увидит тут вызов метода println()
с параметром типа double
.
Компилятор следит, чтобы при вызове метода типы аргументов и параметров совпадали, а на имя аргумента не обращает никакого внимания. В Java имена переменных-параметров никак не помогают компилятору определить вызываемый метод. Поэтому и не учитываются при определении уникальности метода.
Имя метода и типы его параметров называются сигнатурой метода. Пример: sum(int, int)
Каждый класс должен иметь не методы с уникальными именами, а методы с уникальными сигнатурами.