- Объявление метода
- Что означают все эти слова в объявлении метода?
- Как вызвать метод?
- ключевое слово this
- Как читать UML-диаграммы (методы)
- Полезные ссылки
Внимание! На слайде в уроке допущена опечатка: вместо
car.setSpeed(spped)
должно быть car.setSpeed(speed)
.
Внимание! Перед тем как нажать кнопу "далее" внимательно изучите текстовый материал и полезные ссылки!
Объявление метода
Логично, что для появления такого члена класса как метод — его нужно объявить.
Метод не является объектом в 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 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
не требуется, но может быть применено для преждевременного завершения работы метода, по задумке программиста.
- any type (любой тип) и даже
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
.
Полезные ссылки
- Для создания UML - GenMyModel. И всегда можно нагуглить подходящий редактор именно для Вас.
- Методы в Java - Oracle
- Методы в Java- Tutorialspoint
- Использование ключевого слова this