Создание (определение) функции

Пора научиться создавать собственные функции! Код, в котором создаётся функция, называется определением функции.

Вот простейший пример функции, которая печатает в консоль ‘“Hello world!”‘ (напомним, это побочный эффект):

static void sayHello() {
  System.out.println("Hello world!"); // => Hello world!
}

Первая строка описания функции называется заголовком. Заголовок обычно состоит из:

  • модификаторов
  • типа возвращаемого значения
  • названия функции
  • параметров (аргументов) функции.

Задача функции - выполнить действия, указанные в { }.

Модификаторы определяют, как функцию можно вызвать в программе. static означает, что функция не пользуется членами того класса, к которому относится (напомним, в Java всякая функция относится к какому-то классу, но классы мы в этом курсе не изучаем).

Также в описании функции можно указать модификаторы доступа. Например, модификатор public означает, что функцию можно вызвать в любой части программы.

Функции могут возвращать или не возвращать значения, могут вызываться с указанием параметров или без. Если результатом работы функции будет конкретное значение (например, минимальное из двух чисел или имя родителя), тип этого возвращаемого значения указывают при определении функции — перед её именем.

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

Если для работы функции нужны исходные данные (например, числа или текст), то в описании функции их перечисляют в круглых скобках (). В примере выше параметры не нужны, поэтому скобки оставили пустыми.

Чтобы Java-приложение могло работать, в каком-то его классе обязательно нужно объявить такую функцию main(), как мы делали ранее во всех примерах:

public static void main(String[] args) {

}

Именно эта функция и будет вызвана при запуске приложения, поэтому в ней мы и писали код, который хотели выполнить. В примерах мы объявляли эту функцию в классе App.

Создадим нашу первую функцию. У неё будет одна задача: выводить на экран текст Today is: December 5.

Нужно назвать функцию так, чтобы из названия была понятна её задача. Давайте дадим ей имя showDate():

static void showDate() {
  var text = "Today is: December 5";
  System.out.println(text); // => Today is: December 5
}

В нашей функции только две строчки кода, но их может быть сколько угодно. Функции можно считать программами внутри программ.

Вот полная программа, c определением функции и вызовом:

public class App {
  public static void main(String[] args) {
    App.showDate();
  }

  static void showDate() {
    var text = "Today is: December 5";
    System.out.println(text);
  }
}

В ней не только функция main(), но и showDate() описана в классе App, поэтому функция showDate() вызывается выражением App.showDate(). Но на самом деле, если обе функции описаны в одном и том же классе, как здесь, то одна из них может вызывать другую без указания имени класса: не App.showDate(), а просто showDate().

Today is: December 5

Мы могли бы использовать подобную функцию на сайте или в какой-нибудь программе, чтобы выводить текущую дату на экран. Но в текущем виде функция не справится с задачей, ведь она всегда выводит Today is: December 5.

Давайте улучшим функцию так, чтобы она принимала дату в качестве аргумента и выводила её на экран.

Определим и вызовем нашу обновленную функцию:

public static void main(String[] args) {
  showDate("January 29");
}

static void showDate(String date) {
  var text = "Today is: " + date;
  System.out.println(text);
}
Today is: January 29

Теперь понятно, зачем нужны были круглые скобки после имени функции: в них можно указать аргументы. Теперь наша функция принимает один аргумент — date, имеющий тип String (так называется в Java тип, соответствующий строке текста).

Заметьте: мы не создаём переменную date, но используем её в теле функции. Java работает так: переменная сама создаётся при вызове и указанное значение (в нашем примере — "January 29") записывается в эту переменную.

Аргументов может быть несколько. В таком случае в определении функции мы делаем то же самое, что в вызове: просто указываем аргументы через запятую, записывая тип и имя для каждого.

Аргументы можно называть как угодно, их имена имеют смысл исключительно в теле функции.


Полный пример определения функции с несколькими аргументами и её вызова:

public static void main(String[] args) {
  showDate("January", "29");
}

static void showDate(String month, String day) {
  var text = "Today is: " + month + " " + day;
  System.out.println(text);
}
Today is: January 29

Главное — помнить про порядок: в каком порядке аргументы стоят при определении функции, в таком же порядке они должны передаваться при вызове.

Задание

Реализуйте функцию printMotto(), которая печатает на экран фразу Winter is coming.

printMotto(); // => Winter is coming

Чтобы мы могли вызвать эту функцию из другого класса, нужно ее пометить не только ключевым словом static, но еще и public.

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


Советы


Нашли ошибку? Есть что добавить? Пулреквесты приветствуются https://github.com/hexlet-basics
Если вы столкнулись с трудностями и не знаете, что делать, задайте вопрос в нашем большом и дружном cообществе
Упражнение доступно только авторизованным пользователям.

Пожалуйста, авторизуйтесь, это необходимо для отслеживания прогресса выполнения уроков. Если у вас ещё нет учётной записи, то сейчас самое время создать аккаунт.