Чем отличается конструктор от метода java
Перейти к содержимому

Чем отличается конструктор от метода java

  • автор:

Конструктор

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

Конструктор инициализирует объект непосредственно во время создания. Имя конструктора совпадает с именем класса, включая регистр, а по синтаксису конструктор похож на метод без возвращаемого значения.

 private int Cat(); // так выглядит метод по имени Cat Cat(); // так выглядит конструктор класса Cat 

В отличие от метода, конструктор никогда ничего не возвращает.

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

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

 class Box < int width; // ширина коробки int height; // высота коробки int depth; // глубина коробки // Конструктор Box() < width = 10; height = 10; depth = 10; >// вычисляем объём коробки int getVolume() < return width * height * depth; >> 

Мы временно удалили метод setDim() и добавили конструктор. Посмотрим, что получится:

 Box catBox = new Box(); mInfoTextView.setText("Объём коробки: " + catBox.getVolume()); 

Программа выведет объём коробки, хотя мы не задавали никаких размеров для неё. Благодаря конструктору любая создаваемая коробка будет иметь какой-то зафиксированный объём.

Естественно, вы можете вернуть обратно метод setDim() (см. статью про классы) и установить свои размеры для коробки:

 Box catBox = new Box(); // установим свои размеры для коробки catBox.setDim(10, 20, 30); mInfoTextView.setText("Объём коробки: " + catBox.getVolume()); 

Теперь вам должно быть ясно, что когда после ключевого слова new мы пишем имя класса со скобками, то на самом деле мы вызываем конструктор класса.

Возникает вопрос — но ведь сначала при создании класса мы не создавали конструктор, однако код new Box() работал. Дело в том, что если конструктор не определён явно, то Java создаст конструктор, который будет использоваться по умолчанию. В этом случае он просто присвоит всем переменным нулевые значения. Если вы создали сами конструктор, то конструктор по умолчанию использоваться не будет.

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

 Cat cat = new Cat(8); // коту 8 лет 

Если Cat(int) является единственным конструктором класса, то компилятор не позволит создавать объекты Cat каким-либо другим способом.

Однако вернёмся к коробкам для котов. Созданный нами конструктор не особо полезен, так как создаёт одинаковые коробки. Создадим конструктор с параметрами в классе Box и закомментируйте первый конструктор без параметров:

 // Второй конструктор Box(int w, int h, int d)

Если класс содержит один конструктор с параметрами, то вам придётся обязательно указать значения при объявлении класса:

 // Это конструктор теперь не допустим // Box catBox = new Box(); // В конструкторе нужно указать значения размеров коробки Box catBox = new Box(100, 200, 100); mInfoTextView.setText("Объём коробки: " + catBox.getVolume()); 

Кстати, с таким конструктором метод setDim() нам уже не нужен. Мы можем задать размеры коробки сразу в конструкторе. Так как скорее всего коробка постоянна и не меняет своих размеров, то метод, пожалуй, лишний. Но если мы будем менять размеры коробки, то метод придётся оставить.

Класс может иметь несколько конструкторов. Снимите комментарий с первого конструктора и создайте две коробки — коробку по умолчанию и большую коробку.

 Box defaultBox = new Box(); mInfoTextView.setText("Объём стандартной коробки: " + defaultBox.getVolume()); Box bigBox = new Box(100, 200, 200); mInfoTextView.append("\nОбъём большой коробки: " + bigBox.getVolume()); 

То есть, мы видим, что конструкторы поддерживают перегрузку, как и методы.

Например, мы можем создать ещё один конструктор специально для коробки в виде куба, где все стороны равны:

 // Третий конструктор для куба Box(int len)

Вычисляем размер куба:

 Box cube = new Box(5); int vol = cube.getVolume(); mInfoTextView.setText("Объём куба: " + vol); 

Используем объект в качестве параметров

Мы пока использовали в качестве параметров в конструкторах простые типы. Но можно передать и объект самого класса. Добавим ещё один конструктор:

 // Используем объект типа Box Box(Box ob)

В коде программы можно воспользоваться конструктором следующим образом:

 Box box1 = new Box(100, 200, 100); Box cloneBox = new Box(box1); int vol = cloneBox.getVolume(); mInfoTextView.setText("Объём коробки: " + vol); 

Класс Box (исходник)

 package ru.alexanderklimov.box; class Box < int width; // ширина коробки int height; // высота коробки int depth; // глубина коробки // Конструктор Box() < width = 10; height = 10; depth = 10; >// Второй конструктор Box(int w, int h, int d) < width = w; height = h; depth = d; >// Третий конструктор для куба Box(int len) < width = height = depth = len; >// Используем объект типа Box Box(Box ob) < width = ob.width; height = ob.height; depth = ob.depth; >// вычисляем объём коробки int getVolume() < return width * height * depth; >// устанавливаем размеры коробки void setDim(int w, int h, int d) < width = w; height = h; depth = d; >> 

Вызов перегруженных конструкторов через this()

Имея дело с перегруженными конструкторами, удобно один конструктор вызывать из другого через ключевое слово this. При выполнении конструктора this() сначала выполняется перегруженный конструктор, который соответствует списку параметров. Затем выполняются операторы, находящиеся внутри исходного конструктора, если таковые существуют. Вызов конструктора this() должен быть первым оператором в конструкторе.

Для начала создадим класс, который не использует конструктор this(), чтобы понять разницу.

 class Cat < int age; int birthday; // Инициализируем переменные явно Cat(int i, int j) < age = i; birthday = j; >// Инициализируем переменные одним и тем значением Cat(int i) < age = i; birthday = i; >// Присвоим значения по умолчанию 0 Cat() < age = 0; birthday = 0; >> 

Мы создали класс с тремя конструкторами. Перепишем класс, используя конструктор this().

 class Cat < int age; int birthday; // Инициализируем переменные явно Cat(int i, int j) < age = i; birthday = j; >// Инициализируем переменные одним и тем значением Cat(int i) < this(i, i); // вызывается Cat(i, i); >// Присвоим значения по умолчанию 0 Cat() < this(0); // вызывается Cat(0); >> 

У нас теперь только один конструктор, который присваивает значения полям — Cat(int, int). Что происходит при выполнении оператора:

 Cat cat = new Cat(8); 

Вызов конструктора Cat(8) приводит к выполнению конструктора this(8, 8), что равнозначно вызову конструктора Cat(8, 8).

Что происходит при выполнении оператора:

 Cat cat2 = new Cat(); 

В этом случае вызывается конструктор this(0), что приводит к выполнению конструктора Cat(0), поскольку именно эта версия конструктора подходит по списку параметров. При этом конструктор Cat(0) по сути вызывает конструктор Cat(0, 0).

Использование перегруженных конструкторов через конструктор this() позволяет исключить дублирование кода, уменьшая время загрузки классов.

Но следует быть осторожным, так как конструкторы, которые вызывают конструктор this(), выполняются немного медленнее.

Закрытый конструктор

Иногда класс создаётся только для хранения каких-то статических полей и статических методов. Таким классам принято давать имена Utils, но это не обязательно. Такому классу не нужен конструктор, но если автор класса его не создал, то система сама создаст конструктор по умолчанию. Такой конструктор не имеет смысла, а также может послужить источником ошибок. Чтобы предохраниться от подобной проблемы вы сами явно должны создать пустрой конструктор и сделать его закрытым.

 public class Utils < private Utils() < throw new AssertionError(); >. //ваш правильный код // Неправильный код, только для демонстрации! public static void someMethod() < Utils utils = new Utils(); utils.toString(); >> 

Строка throw new AssertionError() не является обязательной, но она поможет выявить ошибку, если вы вызовете конструктор в самом классе. Компилятор пропустит такой вариант, но программа завершится с ошибкой.

 Utils.someMethod(); // программа закроется с ошибкой 

Подкласс для данного класса вы создать не сможете.

Чем отличаются методы от конструкторов в java?

Главное отличие между конструкторами и методами в том, что конструкторы инициализируют объекты, создаваемые с помощью оператора new , в то время как методы выполняют операции с уже существующими объектами.

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

Определение конструкторов и методов похожи. Они могут принимать параметры, иметь модификаторы (т.е. public ), а так же имеют тело которое будет выполняться.

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

Методы должны что-то возвращать, хотя бы void .

Отслеживать
ответ дан 16 июл 2019 в 8:29
81.2k 9 9 золотых знаков 78 78 серебряных знаков 136 136 бронзовых знаков

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

16 июл 2019 в 10:23

@StrangerintheQ, это на самом деле совсем точно 🙂 методы могут быть вызваны напрямую у объекта? — могут. 🙂

Чем конструктор отличается от метода?

Читаю Шилдта и уже 2ой день не могу понять конструкторы. Чем они отличаются от методов? Для чего их необходимо использовать?
Если есть возможность, приведите, пожалуйста, примеры.

  • Вопрос задан более трёх лет назад
  • 2443 просмотра

Комментировать
Решения вопроса 3

DevMan

конструктор – метод, который вызывается автоматически при создании объекта.
Конструктор_(объектно-ориентированное_программирование)

Ответ написан более трёх лет назад
Комментировать
Нравится 4 Комментировать

Dywar

Конструктор — специальный метод, который призван создавать экземпляры класса или структуры. У него нет возвращаемого значения (неявный void).
Дефолтный конструктор — конструктор без аргументов.

Метод тоже может создавать новый экземпляр, но его нельзя вызвать через оператор new . ().

Условно:
Конструктор — метод для создания экземпляра.
Метод — это поведение созданных экземпляров.

var a = new Constructor();
a.Method();

Ответ написан более трёх лет назад
Комментировать
Нравится 4 Комментировать

Как уже говорилось ранее конструктор это метод, вызывающийся для создания экземпляра объекта, не содержит возвращаемого значения. Его можно использовать только с оператором new, он также может быть без аргументов (конструктор по умолчанию или дефолтный) или с ними, также конструктор нельзя передать ни в один метод, но вам стоит почитать про this и base, они часто применяются к конструкторам, если есть перегрузка или наследование. Но также он делится на два типа статический (не используется для создания, а лишь к нему подготавливает — т.е. устанавливает значения свойств, переменных, которые вы либо явно указали, либо их значения по умолчанию) — он не может иметь аргументов, а значит и перегрузок, а также методов доступа (указывается без него), вызывается в неявном виде перед любым другим конструктором объекта и нестатический — тот, что указывается в new с аргументами или без, а также с методами доступа. Конструктор без аргументов может быть использован в ограничениях, потому его отделяют в понятиях. Это бывает важным например для создания окон и любых форм.

Ответ написан более трёх лет назад
Комментировать
Нравится 3 Комментировать
Ответы на вопрос 0
Ваш ответ на вопрос

Войдите, чтобы написать ответ

c#

  • C#

Что за таблица теневых страниц? Как их выделить, какая функция?

  • 1 подписчик
  • 3 часа назад
  • 19 просмотров

Отличия конструкторов от обычных методов.

Java-университет

Конструктор — это специальный метод, который предназначается для первичной установки значений полей объекта. На первый взгляд конструкторы объектов не сильно отличаются от обычных методов объекта. И действительно внутри конструктора мы можем делать всё то же, что и в обычных методах объекта: выводить текст в консоль, обращаться ко всем полям и методам нового объекта, выбрасывать исключения и так далее. Так же как и обычные методы, конструкторы могут иметь аргументы. Так же как и перегруженных методов, конструкторов может быть несколько с различными сигнатурами. Так же как и дженерик-методы конструкторы могут быть параметризованы переменными типов. Даже если мы заглянем в байт-код генерируемый компилятором, в месте где должен быть вызов конструктора, мы обнаружим обращение к некоторому методу с именем вызов которого не отличается от вызова других методов объекта. А найдя байт-код этого метода мы обнаружим, что он и содержит результат компиляции нашего конструктора. Кажется что отличий от обычных методов не много, но они есть, и довольно существенные. Для начала давайте разберёмся, а для чего нам собственно нужны конструкторы? Для хранения и обработки каких либо данных, будь то примитивные типы, массивы, или объекты нам необходим некоторый объём памяти. Это могут быть регистры процессора, место на стеке, либо кусочек пространства, выделенный в секции данных процесса, либо в динамически размещаемой части памяти (куче). Во многих языках программирования, в целях ускорения, при запросе программой нового кусочка памяти, память отдавалась программе не отчищенной, и могла содержать произвольные данные, которые были сохранены в этой ячейки памяти ранее. Подготовка и запись в такой кусок памяти необходимых значений, чтобы в итоге там оказался какая-либо осмысленная структура данных, ложилась целиком на плечи программиста. Вполне естественно программисты хотели облегчить себе жизнь и писали подпрограммы для инициализации (то есть установки начальных значений) для часто используемых структур данных. Такие подпрограммы применялись практически постоянно, так что создатели языка Java, решили сделать подобные подпрограммы инициализации обязательными для вызова при создании объектов, и назвали их конструкторами. Когда в Java создаётся новый объект происходит следующее: Сначала менеджер памяти Java выделяет объём памяти необходимый для размещения объекта. При этом учитываются не только поля объявленные непосредственно в классе создаваемого объекта, но так же поля объявленные во всех предках этого класса. Дополнительно в этот объем включается пространство для размещения структур которые используются Java-машиной для внутренних нужд. Все поля такой «заготовки» автоматически устанавливаются в дефолтные значения — null для ссылочных типов, 0 для чисел и false для boolean . После этого, автоматически вызывается конструктор класса, задача которого установить начальные значения полей объекта. Если в обычном методе первый оператор может быть любым, то у конструктора гораздо меньше свободы. Первым оператором конструктора должен быть либо явный вызов другого конструктора того же класса, либо явный или неявный вызов конструктора родительского класса. Явный вызов конструкторов того же класса осуществляется с помощью ключевого слова this за которым следует набор аргументов заключённый в скобки. Явный вызов конструктора родительского класса производится точно так же, но при этом используется ключевое слово super . В аргументах явного вызова конструктора того же, либо родительского класса нельзя обращаться к полям и методам объекта, равно как и использовать ключевые слова this и super , так как явный вызов конструктора вводит статический контекст. Для неявного вызова конструктора родительского класса писать ничего не надо, но при этом неявно вызывается конструктор по-умолчанию, который должен существовать и быть видимым для текущего класса. При этом, следует иметь ввиду, что если цепочка вызова родительских конструкторов прервётся до того как конструктор класса Object , находящийся на вершине цепочки, успешно завершит свою работу, то объект не будет финализируемым, то есть метод finalize() такого объекта никогда вызван не будет. После завершения работы конструктора родительского класса, управление неявно передаётся на блоки инициализаторов экземпляра и инициализаторы полей экземпляра текущего класса. Инициализаторы исполняются в том порядке, в каком они встречаются в тексте программы. Лишь после завершения работы инициализаторов управление передаётся оставшейся части конструктора. Остальные особенности конструкторов касаются модели памяти Java. Если класс, либо один из его предков, переопределяет метод finalize() , то завершение работы конструктора случится до (happens-before) запуска метода finalize() . Если какой-либо поток увидел ссылку на объект после завершения работы конструктора, то гарантируется что этот поток увидит корректно инициализированные final -поля объекта, инициализация которых произошла до завершения работы конструктора.

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

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