Заведём жабу? Часть 7.

Конструктор

Конструктор — это блок кода внутри класса, который вызывается перед созданием объекта. У конструктора одна цель — создание экземпляра класса с заранее определённым состоянием. Под состоянием понимается совокупность значений переменных класса или по другому свойств класса. Конструктор позволяет перед созданием объекта присвоить этим переменным начальные значения, а не оставлять их «по умолчанию»

Конструктор — это НЕ МЕТОД (хотя в некоторой литературе встречается определение «метод, который инициализирует объект») и не надо его путать с методом.

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

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

Когда в прошлых уроках мы создавали объект Computer, писали так Computer comp = new Computer();

В данном случае мы вызывали «конструктор по умолчанию», который создаётся автоматически компилятором, если другие конструкторы не указаны. Теперь мы создадим наши личные конструкторы. Перейдём в класс Computer. Создание конструктора начинается с модификатора доступа. Пусть будет public — видео везде. КОНСТРУКТОР НЕ ИМЕЕТ НИКАКИХ ВОЗВРАЩАЕМЫХ ЗНАЧЕНИЙ! Даже void писать НЕ НУЖНО! Название конструктора должно совпадать с именем класса. То есть имя конструктора будет Computer. Затем в фигурных скобках указываем параметры, которые будут передаваться в этот конструктор. Само собой конструктор пишется внутри класса.

К примеру мы хотим создать объект с начальным значением имени. Выглядеть это будет примерно так:

 

public Computer (String name) {
        
        this.name = name;
    }

 

name — у нас переменная типа String. В фигурных скобках мы присваиваем переменной класса computer name новое значение переданному параметру name. Напишем так name = name. Мы хотим, чтобы левая переменная name относилась к переменной класса Computer, а правая переменная name относилась к переданному параметру name, но так как их имена совпадают компилятор не может разобраться какую переменную и куда мы хотим записать. Чтобы выполнить эту задачу, следует воспользоваться ключевым словом this (этот).

Слово this обозначает, что мы используем какой-либо элемент текущего класса или объекта. В данном случае мы из текущего объекта находим переменную name и в неё мы записываем переданный параметр name. Правый nsme — переданный параметр, а левый name — переменная нашего класса.

Ключевое слово this указывает на ссылку для текущего объекта Computer. Таким образом мы можем передавать переменную с таким же именем, что и переменная класса. Если мы будем использовать ключевое слово this, то путаницы не будет.

Давайте создадим конструктор для переменной ram. Делаем по аналогии с name, только тип переменной уже будет int.

    public Computer (int ram) {
        
        this.ram = ram;
    }

В качестве входного параметра первый конструктор принимает имя, второй размер оперативной памяти. Теперь давайте попробуем создать наш объект при помощи конструктора. Перейдём в файл MyFirstProgram.java Напротив строки Computer comp = new Computer(); можно увидеть горящий символ — компилятор «говорит,» что нет такого конструктора для объекта Computer. Потому что раньше мы использовали «конструктор по умолчанию» без параметров (в скобках нет параметров), который создавала сама виртуальная машина Java автоматически, поскольку никаких конструкторов мы не прописывали.

Теперь мы прописали свои два конструктора и в этом случае действует правило, что если вы написали свои конструкторы, то конструктор «по умолчанию» исчезает, перестаёт действовать из-за чего и «ругается» компилятор.

Но если мы хотим, чтобы был конструктор «по умолчанию», нам в этом случае придётся написать его самим вручную. В качестве параметров ничего не передаётся.


public Computer() {
        
    }

Именно такой конструктор «по умолчанию» без параметров создаёт компилятор, если нет других конструкторов, но в коде он не отображается.

В данном случае нам пришлось вручную написать конструктор без параметров, чтобы мы могли создавать объект, не передавая никаких параметров в конструктор. Теперь компилятор разобрался. Если мы нажмём Ctrl и сделаем щелчок ЛКМ по Computer();, то Netbeans перенесёт нас в файл Computer.java в участок кода


public Computer() {
        
    }

То есть в тот конструктор, который мы вызываем при создании объекта.Давайте создадим конструктор для параметра hdd.


 public Computer (int hdd) {
        
        this.hdd = hdd;
    }

ВАЖНЫЙ МОМЕНТ. МЫ ХОТЕЛИ СОЗДАТЬ КОНСТРУКТОР ДЛЯ ПЕРЕМЕННОЙ HDD, ОДНАКО КОМПИЛЯТОР «РУГАЕТСЯ» ПО ПРИЧИНЕ ТОГО, ЧТО ТАКОЙ КОНСТРУКТОР УЖЕ ОПРЕДЕЛЁН В ОБЪЕКТЕ Computer. Дело в том, что компилятор «смотрит» на список параметров (то есть на передаваемые типы переменных в круглых скобках), не на их названия, а на их типы! В данном случае он «говорит» , что уже есть конструктор с одним параметром типа int. Второй такой же создать нельзя.

Если мы хотим, чтобы у нас было два конструктора с одинаковыми типами параметров и с их одинаковым количеством — то ничего не выйдет — компилятор «запретит» нам это сделать. Как же быть в этой ситуации? Чтобы не писать конструктор для каждой переменной можно создать конструктор, который будет включать в себя все нужные нам переменные, которые есть у класса. Удалим вышеприведённый кусок кода и модифицируем конструктор

 

public Computer (String name) {
        
        this.name = name;
    }

 

в следующий вид

 
   public Computer (String name, int ram, int hdd, int weight) {
        
        this.name = name;
        
        this.ram = ram;
        
         this.hdd = hdd;
         
         this.weight = weight;
    }

Теперь давайте изменим наш код так, чтобы мы присваивали значения не через «сетер,» а перед созданием объекта. Закомментируем следующий участок кода в классе MyFirstProgram, дабы показать, что можно сделать по другому.

       
//     comp.setName("IBM");
//       
//      comp.setRam(2048);
//      
//      comp.setHdd(320);

Для того, чтобы закомментировать выделяем нужный нам диапазон, нажимаем ctrl и наклонный слэшь. Для раскомментирования делаем тоже самое. Изменим строку вызова конструктора так, чтобы вызывался конструктор с параметрами. Вот эта строка: Computer comp = new Computer();

Поставим курсор в скобки и нажмём ctrl + space (пробел). Netbeans предложит на выбор несколько конструкторов с параметрами и без. Выберем тот, где 4 параметра.

 Computer comp = new Computer(null, 0, 0, 0);

Теперь мы можем передать какие-то значения. Давайте передадим те значения, которые остались у нас в закомментированных «сетерах.» Имя — IBM, Оперативная память — 2048, Объём жесткого диска — 350, вес пусть будет — 2.


Computer comp = new Computer("IBM", 2048, 320, 2);

Давайте теперь запустим нашу программу. Программа выведет что-то вроде:

run:
Я включился. Моя модель IBM
Я загружаюсь. Мой объём жесткого диска равен 320 ГБ
Я выключился
СБОРКА УСПЕШНО ЗАВЕРШЕНА (общее время: 0 секунд)

То есть теперь мы присвоили значения переменным объекта Computer ДО СОЗДАНИЯ объекта Computer. А в прошлый раз мы создавали объект Computer, используя конструктор «по умолчанию,» и только затем после создания мы использовали «сетеры» для присвоения значений переменных.

Конструктор создаёт объект уже с начальным состоянием. В прошлый же раз у нас было состояние «по умолчанию,» которое мы изменяли при помощи «сетеров.»

Обратите внимание на данную схему. Самый упрощённый вариант работы конструктора такой:конструктор имеет несколько входных параметров, на схеме у нас 4 параметра, после вызова конструктора значения этих параметров записываются в переменные класса. Таким образом до инициализации объект получает какое-то начальное состояние или по-другому значения переменных класса.

То есть последовательность такая: запись значения в переменных класса и только после этого создание объекта.

Конструктор и метод внешне похожи, но назначение их разное. От метода конструктор отличается тем, что у него НЕТ типа возвращаемого значения, нет даже void.

Конструктор имеет имя такое же, как у класса. Методы же можно называть как угодно и только никак название класса.

Если никакой конструктор не указан — компилятор автоматически создаёт конструктор по умолчанию. (без параметров)

Следует различать конструктор «по умолчанию» (созданный автоматически компилятором), и конструктор без параметров, созданный программистом (в этот конструктор программист ещё может добавить какую-то логику работы, чего нет в конструкторе от компилятора).

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

Конструктор также имеет модификатор доступа!

Если программист в коде написал какой-то свой конструктор, то конструктор «по умолчанию» не создаётся!

Netbeans позволяет быстро создавать конструктор. Для этого следует нажать ctrl+space(пробел). Используя этот способ всё, что мы писали вручную — можно было создать автоматически.

Обратите внимание на неточность в нашем предыдущем конструкторе.


public Computer (String name, int ram, int hdd, int weight) {
        
        this.name = name;
        
        this.ram = ram;
        
         this.hdd = hdd;
         
         this.weight = weight;
    }

А именно переменная weight является типа double, но в вышеприведённом участке кода она отображена как int и компилятор это воспринял. Это произошло потому, что double включает в себя как и целые числа, так и числа с плавающей точкой. То есть диапазон типа double намного шире диапазона типа integer, поэтому мы можем передавать целое число, но записать его в тип double.

Однако так делать не рекомендуется, поскольку может возникнуть путаница. К примеру если мы хотим передать значения веса в 2 килограмма 200 граммов — ничего не выйдет, поскольку тип переменной weight в конструкторе integer. А вот 2 килограмма вполне себе запишутся в переменную weight с типом double и никаких проблем не будет. Но лучше указывать тип, который нужен ДЛЯ ПЕРЕМЕННОЙ КЛАССА. Исправим на double.


public Computer (String name, int ram, int hdd, double weight) {
        
        this.name = name;
        
        this.ram = ram;
        
         this.hdd = hdd;
         
         this.weight = weight;
    }

Поделиться ссылкой:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *