1. Синтаксис создания классов

Создадим класс Box, который описывает контейнер, допустим, на каком-то складе.

Box.java
public class Box {
    
    double width;
    double height;
    double depth;
    
}

Класс Box определяет три переменные экземпляра: width (ширина), height (высота) и depth (глубина). В настоящий момент класс Box не содержит никаких методов.

Как мы уже говорили, класс определяет новый тип данных. В данном случае новый тип данных называется Box. Это имя будет использоваться для объявления объектов типа Box. Не следует забывать, что объявление class создает только шаблон, но не конкретный объект. Таким образом, приведенный выше код не приводит к появлению каких-нибудь объектов типа Box.

Чтобы действительно создать объект класса Box, нужно воспользоваться оператором new

Main.java
public class Main {
    public static void main(String[] args) {

        Box myBox = new Box();
    }
}

После выполнения этого оператора объект myBox станет экземпляром класса Box. Таким образом, он обретет "физическое" существование.

Также следует напомнить, что каждый объект содержит собственную копию переменной экземпляра, которая определена в классе. Каждый объект типа Boxбудет содержать собственные копии переменных width, height и depth(рис. 4.2).

Изменения в переменных экземпляра одного объекта не влияют на переменные экземпляра другого объекта. Таким образом, каждый объект класса Box будет содержать собственные копии переменных width, height и depth. Для доступа к этим переменным служит оператор-точка (.). Эта операция связывает имя объекта с именем переменной экземпляра. Например, чтобы присвоить переменной width экземпляра myBox значение 100, нужно выполнить следующий оператор:

myBox.width = 100;

Этот оператор предписывает компилятору, что копии переменной width, хранящейся в объектe myBox, требуется присвоить значение 100. В общем, операция-точка служит для доступа как к переменным экземпляра, так и к методам в пределах объекта.

Ниже приведет пример программы, в которой используется класс Box

public class Main {
    public static void main(String[] args) {

        // Создаем объект типа Box
        Box myBox = new Box();

        // Присваиваем значения переменным экземпляра myBox
        myBox.width = 10;
        myBox.height = 20;
        myBox.depth = 15;

        // Рассчитываем объем коробки
        double volume = myBox.width * myBox.height * myBox.depth;

        System.out.println("Объем равен: " + volume);
    }
}

Как пояснялось ранее, каждый объект содержит собственные копии переменных экземпляра. Это означает, что при наличии двух объектов класса Box каждый из них будет содержать собственные копии переменных width, height и depth. Следует, однако, иметь ввиду, что изменения в переменных экземпляра одного объекта не влияют на переменные экземпляра другого. Например, в следующей программе объявлены два объекта класса Box:

public class Main {
    public static void main(String[] args) {

        Box myBox1 = new Box();
        Box myBox2 = new Box();

        // Присваиваем значения для mybox1
        myBox1.width = 10;
        myBox1.height = 20;
        myBox1.depth = 15;

        // Присваиваем значения для mybox2
        myBox2.width = 3;
        myBox2.height = 6;
        myBox2.depth = 9;

        double volume;

        // объем первой коробки
        volume = myBox1.width * myBox1.height * myBox1.depth;
        // будет выведено 3000
        System.out.println("Объем равен: " + volume);

        // объем второй коробки
        volume = myBox2.width * myBox2.height * myBox2.depth;
        // будет выведено 162
        System.out.println("Объем равен: " + volume);
    }
}

Программа выводит следующий результат:

Объем равен: 3000.0
Объем равен: 162.0

Как видите, данные из объекта myBox1 полностью изолированы от данных, содержащихся в объекте myBox2.

Методы класса

Как упоминалось ранее, классы состоят из двух компонентов: переменных экземпляра и методов. Общая форма метода выглядит следующим образом:

[возвращаемый тип] имя ([список параметров]) {
    [тело метода]
}

где возвращаемый тип означает конкретный тип данных, возвращаемый методом. Он может быть любым допустимым типом данных, в том числе и типом созданного класса. Если метод не возвращает значение, то его возвращаемым типом должен быть void. В качестве имени методов может быть любой допустимый идентификатор, кроме тех, которые уже используются другими элементами кода в текущей области действия. А список параметров обозначает последовательность пар "тип-идентификатор", разделенных запятыми. По существу, параметры - это переменные, которые принимают значения аргументов, передаваемых методу во время его вызова. Если у метода отсутствуют параметры, то список параметров оказывается пустым. Методы, возвращаемый тип которых отличается от void, возвращают значение вызывающей части программы с помощью оператора return.

Вернемся к нашему примеру с классом Box. Было бы логично, если бы расчет объема коробки выполнялся в классе Box, поскольку объем коробки зависит от ее размеров. Для этого добавим в класс Box метод getVolume()

Box.java
class Box {

    double width;
    double height;
    double depth;
    
    void getVolume() {
        System.out.print("Объем коробки равен ");
        System.out.println(width * height * depth);
    }
}

Внимательно рассмотрим две следующие строки кода

mybox1.volume();
mybox2.volume();

В первой строке вызывается метод volume() для объекта myBox1. Следовательно, метод volume() вызывается по отношению к объекту myBox1, для чего было указано имя объекта, а вслед за ним - операция-точка. Таким образом, в результате вызова метода myBox1.volume() выводится объем коробки, определяемого объектом myBox1, а в результате вызова метода myBox2.volume() - объем коробки, определяемого объектом myBox2.

При вызове метода myBox1.volume() исполняющая система Jаvа передает управление коду, определенному в теле метода volume(). По окончании выполнения всех операторов в теле метода управление возвращается вызывающей части программы и далее ее выполнение продолжается со строки кода, следующей за вызовом метода. В самом общем смысле метод - это способ реализации подпрограмм в Java.

В методе volume() следует обратить внимание на еще одну очень важную особенность: ссылка на переменные экземпляра width, height и depth делается непосредственно без указания перед ними имени объекта или операции-точки. Когда в методе используется переменная экземпляра, определенная в его же классе, это делается непосредственно, без указания явной ссылки на объект и применения операции-точки . Это становится понятным, если немного подумать. Метод всегда вызывается по отношению к какому-то объекту его класса. Как только этот вызов сделан, объект известен. Таким образом, в теле метода вторичное указание объекта совершенно излишне. Это означает, что переменные экземпляра width, height и depth неявно ссылаются на копии этих переменных, хранящиеся в объекте, который вызывает метод volume().

Подведем краткие итоги. Когда доступ к переменной экземпляра выполняется из кода, не входящего в класс, где определена переменная экземпляра, следует непременно указать объект с помощью операции-точки. Но когда такой доступ осуществляется из кода, входящего в класс, где определена переменная экземпляра, ссылка на переменную может делаться непосредственно. Эти же правила относятся и к методам.

Следует обратить внимание, что метод getVolume() возвращает значение 3000, и это значение рассчитанного объема сохраняется в переменной vol. При обращении с возвращаемыми значениями следует принимать во внимание два важных обстоятельства:

  • тип данных, возвращаемых методом, должен быть совместим с возвращаемым типом, указанным в методе. Так, если какой-нибудь метод должен возвращать логический тип boolean, то возвратить из него целочисленное значение нельзя;

  • переменная, принимающая возвращаемое методом значение (например, vol), также должна быть совместима с возвращаемым типом, указанным для метода.

Last updated