Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Модуль 3. Урок 1. Основы использования и создания методов в классах. Введение в Java

Видео может быть заблокировано из-за расширений браузера. В статье вы найдете решение этой проблемы.

alt text Внимание! На слайде в уроке допущена опечатка: вместо car.setSpeed(spped) должно быть car.setSpeed(speed).

alt text Внимание! Перед тем как нажать кнопу "далее" внимательно изучите текстовый материал и полезные ссылки!

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

Логично, что для появления такого члена класса как метод — его нужно объявить.

Метод не является объектом в java сам по себе. Он всегда привязан к конкретному классу или объекту этого класса.

Метод объявляется всегда внутри тела класса. То есть между открывающей и закрывающей скобками класса. Желательно это делать после объявления всех полей класса.

Метод не может быть объявлен:

  • внутри другого метода;
  • отдельного блока кода в пределах класса;
  • за пределами класса;
  • внутри условных операторов, циклов и пр.

Исключение составляют анонимные классы. Но об этом будет отдельный урок.

Объявление метода состоит из:

  • модификатора доступа (private, package-private aka default, protected, public);
  • модификатора уровня (static or not);
  • возвращаемого типа;
  • идентификатора этого метода (имя, по которому к нему можно будет обратиться);
  • аргументов в круглых скобках, которые пишутся сразу за идентификатором, без пробелов (methodName(int a, int b));
  • фигурных скобок, в которые заключено тело метода.

Пример 1:

public class SomeAuxiliaryClass {

    public int multiply(int number){
        return number * number;
    }
}

Пример 2:

public class SomeAuxiliaryClass {

    public int multiply(int number){
        return number * number;
    }

    public static void uselessMethod(int a, int b) {
        int result = a + b;
        System.out.println("I will not say the result! Ha ha ha ha!");
    }
}

Пример 3:

public class SomeAuxiliaryClass {

    private int some counter = 0;

    public int getCounter(){
        return counter;
    }
}

Что означают все эти слова в объявлении метода?

Разберем этот вопрос на примере метода, с которого начинается каждая программа:

public static void main (String[] args) {
   ... // некий код в теле метода
}
  • public — это модификатор доступа (видимости). Конкретно public говорит, что этот метод доступен любому внешнему классу или программе.

    Более детально о модификаторах доступа расскажем в пятом модуле.

  • static — это модификатор, отвечающий за уровень метода. Если есть такой модификатор — метод находится на уровне класса, а не объекта. Если нет модификатора static — метод уровня объекта!

    Уровень метода:

    + или class level
    + или instance level (without keyword)
    

Детально эта тема будет рассмотрена буквально через урок.

  • void — конкретно это ключевое слово говорит, что метод ничего не возвращает. На его месте может быть любой тип из мира java — такой тип и должен возвращать метод.

    Что может возвращать метод:

    • any type (любой тип) и даже null. Не важно что это, примитив или ссылочный тип. Но обязательно должно быть ключевое слово return в теле метода.
    • void --> Просто ничего не возвращать. Даже null. Ключевое слово return не требуется, но может быть применено для преждевременного завершения работы метода, по задумке программиста.
  • main — это идентификатор, имя метода. Конкретно в случае с main-методом — это не просто имя, а метод с которого начинает выполняться вся программа.

    • имя метода:
      • пишется в camelStyle - каждое слово в имени метода пишем с большой буквы, кроме самого первого слова;
      • имя метода должно быть говорящим, как и у переменных. Только в случае с методом - имя должно быть глаголом!
  • (String[] args) — в круглых скобках перечислены аргументы данного метода. Их может и не быть вовсе в каком-то методе, а в каком-то и десяток набежать.

  • ... // некий код в теле метода — это непосредственно тело метода, находящееся между фигурных скобок: {}. Именно внутри этих фигурных скобок и нужно писать логику которая, используя аргументы и поля класса, будет что-то вычислять.

Как вызвать метод?

Разберем на примере следующего класса:

public class Car {

    int DEFAULT_SPEED = 20;
    int actualSpeed = 0;

    public static int getDefaultSpeed() {
        return DEFAULT_SPEED;
    }

    public int getActualSpeed() {
        return actualSpeed;
    }

    public void startEngine(){
        System.out.println("Engine started!");
    }

    public void setSpeed(int newSpeed){
        actualSpeed = newSpeed;
    }

    public void setSpeed(){
        actualSpeed = DEFAULT_SPEED;
    }

}

Для начала создадим объект и ссылку на него: Car car = new Car(); // именно car с маленькой буквы, в данном примере, является ссылкой

Создавать этот объект необходимо в месте, где мы будем его использовать. Пускай это будет main-метод.

public static void main (String[] args) {
   Car car = new Car();
}

Если метод не статический, то для обращения к нему нужно:

  • иметь ссылку на инстанс --> car
  • использовать точку --> car.
  • указать имя метода после точки --> car.startEngine
  • передать аргументы, если они ожидаются --> car.setSpeed(12); или не передать, если не ожидаются --> car.setSpeed();

Вот так это выглядит в коде:

public static void main (String[] args) {
   Car car = new Car();
   car.startEngine();
   car.setSpeed(12);
   car.setSpeed(); //20
}

Если метод статический, то его можно вызвать как через объект так и через имя класса:

  • car.startEngine(); // вызов через объект
  • Car.startEngine(); // вызов через имя класса

Пример:

public static void main (String[] args) {
   Car car = new Car();

   car.getDefaultSpeed(); // Обе эти строки приведут
   Car.getDefaultSpeed(); //  к одинаковому результату
}

Детальнее об этом в уроке про уровни методов.

ключевое слово this

Это ссылка на текущий объект(инстанс). Рассмотрим на примере:

     class Car {

        int speed;

        public void showSpeed() {
            System.out.println(speed); // this в аргументах не принято писать, JVM подставит его перед переменной уровня объекта(инстанс) самостоятельно.
        }

        public void setSpeed(int newSpeed) {
            speed = newSpeed; // опять JVM сама подставила this. Программисту не нужно писать это ключевое слово.
        }
        public void otherSetSpeed(int speed) {
            this.speed = speed; // А вот тут программисту **нужно** указывать this. Чтобы было очевидно какой переменной идет присвоение.
            //Такое совпадение имен встречается, например, в конструкторах (в пятом модуле этого курса расскажем о конструкторах).
        }
    }

    public class Main {

        public static void main(String... args) {
         // тип  /ссылка /присваиваем /инстанциирование объекта
            Car   car     =            new Car();
            // С разметкой в строчке выше все в порядке ;)
            car.speed = 1;
            car.showSpeed();
            car.setSpeed(12);
            car.showSpeed();

            car.otherSetSpeed(5);
            car.showSpeed();
        }
    }

Не стесняйтесь копировать и экспериментировать с кодом локально у себя! И используйте вот этот визуализатор. Он показывает результаты работы отдельных выражений в коде.

Немного модифицированный пример из видео

На наш взгляд этот пример помогает уловить суть происходящего в коде на уроке. Не стесняйтесь тестировать и играться с этим кодом самостоятельно:

public class Car {
    static int speed;

    public static void main(String... args) {
        Car ta4ka = new Car();

        System.out.println("speed в хипе при создании объекта = " + ta4ka.speed); // 0

        ta4ka.setSpeed(12); // Вызываем конкретную функцию(метод) из новосозданного объекта
                            // Значение хранится в фрейме в переменной newSpeed
    }

    public void showSpeed() {    // выводит значение из хипа по ссылке this
        System.out.println("speed в хипе на момент вызова \'showSpeed()\' = " + this.speed);
    }

    public void setSpeed(int newSpeed) { // принимаем значение 12. newSpeed это переменная объявленная внутри метода --> хранится в стеке фрейма метода

        this.speed = newSpeed; // записываем по this-ссылке в хип значение из стека метода setSpeed
        showSpeed();// выводим на экран значение из хипа // 12

        newSpeed = 8;// записали новое значение в стеке в фрейме метода setSpeed

        System.out.println("переменная newSpeed в фрейме метода setSpeed в стеке = " + newSpeed); // 8

        // присваиваем переменной speed новое значение = 3
        speed = 3; // В стеке нет такой переменной, потому значение будет записано в хип!
        System.out.println("Java сама добавила this перед именем \'speed\' и записала новое значение speed в хип = " + this.speed); // 3

        setSetSpeed(newSpeed); // передаем значение newSpeed = 8

    }

    public void setSetSpeed(int speed) { // теперь и только теперь и в фрейме метода setSetSpeed в стеке есть своя переменная c именем speed!

        System.out.println("Значение speed в хипе = " + this.speed); // 3

        speed = speed;//в стеке speed сама себя переприсваивает.
        System.out.println("переменная speed в фрейме стека = " + speed); // 8

        this.speed = speed; // присваиваем значение speed из фрейма значению speed в хипе!
        System.out.println("Значение speed в хипе заданное уже методом setSetSpeed = " + this.speed); // показываем speed из хипа. // 8
    }
}

Как читать UML-диаграммы (методы)

С индикаторами модификаторов доступа Вы уже должны быть знакомы:

+  public
-  private
#  protected
   default (нет никакого модификатора доступа)

Имена полей и их типы в диаграммах пишутся через двоеточие, например: countr: int, name: String. Но в коде, не забывайте, сначала пишем тип, а потом имя.

С методами почти тот же подход, только слов больше.

Например, если в диаграмме написано:

  • + getAge(): int — этот метод public, имеет имя getAge и возвращает объект типа int.
  • - computeSomething(data1: Data, data2: Data): String — этот метод private, имеет имя computeSomething, возвращает объект типа String, на вход принимает два аргумента с именами data1 и data2, оба типа Data.
  • + setName(newName: String): void — это публичный метод с именем setName, ничего не возвращает (void — пустота), принимает на вход аргумент с именем newName типа String.

Полезные ссылки


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

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

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.

Об обучении на Хекслете

Открыть доступ

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

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»