Что такое конструктор в джава
Перейти к содержимому

Что такое конструктор в джава

  • автор:

Конструктор в Java и ключевое слово this- введение в Java-OOP 003 #

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

Принципиально, конструктор — это просто метод. Просто метод который создаёт объекты. В связи с тем, что это очень важный метод и является краеугольным камнем всей парадигмы ООП, то у этого метода есть привилегия.

Конструкторы (методы по которым создаются объекты) — пишутся в java всегда с большой буквы.

Это помогает понять, что сейчас создаётся объект.

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

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

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

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

Иногда в классе нет вообще ни одного конструктора. Именно с такого примера мы и начнём.

Объект есть, конструктора нет #

На нашем (условном) сайте есть статьи и мы создаём Article класс, который поможет нам с ними работать.

public class Article   > class Test   public static void main(String[] args)   Article art = new Article();  > > 

Мы можем создать тестовый класс в том же файле. Мы должны знать, что модификатор доступа Public может применятся только к тому классу, который назван так же как и файл. Дополнительный класс в нашем файле скорее вспомогательный. Этим правилом мы и воспользовались для простоты.

При создании объекта мы использовали пустой конструктор, конструктор без параметров. Но мы его не создавали в классе Article. Так откуда же он взялся?

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

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

В конструкторе мы можем указать начальные или стандартные значения будущих объектов.

public class Article   String title;  String announce;  String fullText;   public Article()   title = "unknown";  announce = "unknown";  fullText = "unknown";  > > 

Для чего нужно создавать много разных конструкторов? #

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

public class Book   private String title;  private String author;  private String isbn;  private int page;  private int year;   public Book()   >   public Book(String bookTitle, String bookAuthor, int bookYear)   title = bookTitle;  author = bookAuthor;  year = bookYear;  >   public Book(String bookTitle, String bookAuthor, String bookIsbn, int bookPage)   title = bookTitle;  author = bookAuthor;  isbn = bookIsbn;  page = bookPage;  > > 

this #

This это ссылка на самого себя, на класс, по которому создаются объекты.

Простейшее применение this уместно в классе выше. Что бы не придумывать новые переменные для конструкторов, отличающиеся от переменных класса, но созвучные им. Мы используем this и как бы говорим: » ЭТА переменная из ПОЛЯ КЛАССА будет равна тому значению, которое мы получим из переменной в сигнатуре конструктора.»

 public Book(String title, String author, int year)   this.title = title;  this.author = author;  this.year = year;  >   public Book(String title, String author, String isbn, int page)   this.title = title;  this.author = author;  this.isbn = isbn;  this.page = page;  > 

Другой пример использования this указан в официальной документации и я просто попытаюсь прочитать его для вам.

public class Rectangle   private int x, y;  private int width, height;   public Rectangle()   this(0, 0, 1, 1);  >  public Rectangle(int width, int height)   this(0, 0, width, height);  >  public Rectangle(int x, int y, int width, int height)   this.x = x;  this.y = y;  this.width = width;  this.height = height;  >  . > 

Строчка “this(0, 0, 1, 1);” указывает на конструктор в этом же методе. И такой конструктор, которые принимает 4 параметра есть — “public Rectangle(int x, int y, int width, int height)”. Вот этот this и вызывает СОБСТВЕННЫЙ конструктор.

Дополнительные ссылки #

  1. Providing Constructors for Your Classes — официальная документация
  2. A Guide to Constructors in Java — www.baeldung.com/java-constructors
  3. Guide to the this Java Keyword this от baeldung
  4. Using the this Keyword — от Oracle

Домашнее задание #

  1. Сколько различных конструкторов можно создать, если у нас девять различных полей класса? Допустим int, double, String, char, long, float, byte, short, boolean.

Конструкторы в Java

конструкторы Java_vertex

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

Шаг за шагом

Итак, чтобы объяснить нагляднее, представим, как работает программа.

1. Вы создаете основное «тело» программы, прописывая метод main:

public class Test < public static void main ( String [ ] args ) <

2. Допустим, Вам нужен объект класса Cat. Класс Cat у вас уже есть, и выглядит он так:

private String name ;
private String color ;
public String getName ( ) < return name ; public void setName ( String a ) < public String getColor ( ) < return color ; public void setColor ( String color ) < this . color = color ;

Вы пишете строку, которая должна создать объект класса Cat:

public class Test < public static void main ( String [ ] args ) < Cat cat1 = new Cat ( ) ;

3. В тот момент, когда программа приступает к созданию объекта cat1, она идет в class Cat:

Тут-то и появляется необходимость в конструкторах. Ведь в первую очередь Java ищет именно конструкторы, которые укажут, как именно создавать объект.

Но в нашем классе есть только геттеры и сеттеры — никаких конструкторов! Что же делать? Теперь объект не создастся?

Создастся, конечно. А все потому, что по-настоящему конструктор все равно присутствует — просто он явно не указан. Теперь, давайте посмотрим как создавать конструкторы явно, и какими они вообще бывают.

Явные и неявные конструкторы

Существуют два вида конструкторов — явные и неявные. Вы уже знаете, что, даже если ничего не прописать в коде класса, Вы все равно сможете «сконструировать» объект этого класса. Но, если все и так работает, зачем их вообще писать? Какие преимущества это дает?

Преимущество 1. Контроль над вводом данных.

Сначала, дайте посмотрим на изображение. Какие отличия Вы видите?

конструкторы Java_vertex

Если Вы заметили, что у всех трех классов разное количество параметров в конструкторе — Вы были правы:

конструкторы Java_vertex

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

Код№1 — класс Cat — скорее всего, был создан с использованием неявного конструктора. Он не просит никаких параметров.

Код№2 — класс Scanner — уже использует явно описанный конструктор. Он требует один параметр — и без него создать объект невозможно.

Код№3 — класс Dog — тоже использует явно описанный конструктор. Но тут, как мы видим, требуется уже три параметра — имя («Шарик»), порода («мопс») и возраст собаки (2 года).

Преимущество 2. Меньше строчек кода.

Вы заметили, как конструктор уменьшает количество строк в коде? Сравните:

Конструкторы

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

  () // заголовок конструктора < // тело конструктора   >

Объявление конструктора очень похоже на объявление метода. Однако следует обратить внимание на следующие ограничения.

  • Модификаторы, кроме модификаторов доступа, недопустимы в заголовке конструктора.
  • Конструктор не может возвращать значение, поэтому не может и задавать в заголовке возвращаемый тип, даже void , но простая форма оператора return может содержаться в теле конструктора.
  • Имя конструктора должно быть таким же, как и имя класса.

Имена классов и методов находятся в разных пространствах имен. Поэтому в примере 4.5 не будет конфликта имен, где метод, объявленный в строке (2), имеет такое же имя, как и конструктор, объявленный в строке (1). Однако использование подобной схемы именования строго не рекомендуется.

Пример 4.5. Пространство имен

public class Name < Name() < // (1) System.out.println("Constructor"); >void Name() < // (2) System.out.println("Method"); >public static void main(String[] args) < new Name().Name(); // (3) за вызовом конструктора следует вызов метода >>
Constructor Method

Конструктор по умолчанию

Конструктор по умолчанию — это конструктор без каких-либо параметров. Другими словами, он имеет следующую сигнатуру:

Если в классе не задано ни одного конструктора, то предоставляется неявный конструктор по умолчанию. Неявный конструктор по умолчанию эквивалентен следующей реализации:

() < super(); >// нет параметров, вызывает конструктор суперкласса.

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

В следующем коде класс Light не определяет никаких конструкторов.

class Light < // поля int noOfWatts; // Мощность boolean indicator; // Включено или выключено String location; // Размещение // нет конструкторов //. >class Greenhouse < // . Light oneLight = new Light(); // (1) вызов неявного конструктора по умолчанию >

В предыдущем коде во время создания объекта Light в строке (1) используется неявный конструктор по умолчанию.

Light()

При создании объекта при помощи оператора new с использованием конструктора по умолчанию, как в строке (1), поля объекта будут проинициализированы соответствующими значениями по умолчанию (т.е. поля noOfWatts , indicator и location в объекте Light будут проинициализированы 0 , false и null соответственно).

Класс может самостоятельно предоставить реализацию конструктора по умолчанию. В следующем примере класс Light явно определяет в строке (1) конструктор по умолчанию. Обратите внимание, что он имеет такое же имя, как и класс, и не получает никаких параметров.

class Light < // . // Explicit Default Constructor Light() < // (1) noOfWatts = 50; indicator = true; location = "X"; >//. > class Greenhouse < // . Light extraLight = new Light(); // (2) Вызов явного конструктора по умолчанию >

Наличие явного конструктора по умолчанию гарантирует, что в любом объекте, созданном с помошью выражения new Light() , как в строке (2), значения полей noOfWatts , indicator и location будут установлены в 50 , true и «X» соответственно.

Если в классе определены какие-либо явные конструкторы, то он не может больше полагаться на неявный конструктор по умолчанию, для установки состояния объектов. Если в таком классе требуется конструктор по умолчанию, то должна быть его реализация. В примере ниже в классе Light задан только конструктор не по умолчанию (1). Он вызывается в строке (2), когда с помощью оператора new создается объект класса light . Любая попытка вызова конструктора по умолчанию будет обозначена как ошибка на этапе компиляции, как показано в строке (3).

class Light < // . // Только конструктор не по умолчанию Light(int noOfWatts, boolean indicator, String location) < // (1) this.noOfWatts = noOfWatts; this.indicator = indicator; this.location = location; >//. > class Greenhouse < // . Light moreLight = new Light(100, true, "Greenhouse"); // (2) OK. // Light firstLight = new Light(); // (3) Ошибка на этапе компиляции >

Перегруженные конструкторы

Как и методы, конструкторы также могут быть перегружены. Так как все конструкторы в классе имеют такое же имя, как и имя класса, то их сигнатуры различаются по их спискам параметров. В следующем примере класс Light поддерживает как явную реализацию конструктора по умолчанию в строке (1), так и конструктор не по умолчанию (2). Конструкторы перегружены, как явно следует из их сигнатур. Конструктор не по умолчанию вызывается, когда создается объект класса Light в строке (3), подобным же образом вызывается и конструктор по умолчанию в строке (4).

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

class Light < // . // Явный конструктор по умолчанию Light() < // (1) noOfWatts = 50; indicator = true; location = "X"; >// Конструктор не по умолчанию Light(int noOfWatts, boolean indicator, String location) < // (2) this.noOfWatts = noOfWatts; this.indicator = indicator; this.location = location; >//. > class Greenhouse < // . Light moreLight = new Light(100, true, "Greenhouse"); // (3) OK. Light firstLight = new Light(); // (4) OK. >

Что такое Конструктор в Java?

Конструктор класса очень удобен и по своему виду схож с обыкновенными функциями. За счёт конструктора мы можем установить значения для объекта сразу при его создании.

Конструктор должен иметь одинаковое название с классом. Пример создания конструктора показан ниже:

class Book < private int pages; public String name; private float weight; public void getInfoBook () < System.out.print("В книге " + name + " находиться " + pages + " страниц. "); System.out.print("При этом она весит " + weight + "кг!"); System.out.println(""); >Book (int pages, float weight) < this.pages = pages; this.weight = weight; >Book (int pages, float weight, String name) < this.pages = pages; this.weight = weight; this.name = name; >>

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

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

В коде выше переменные идут с модификатором доступа private . Дело в том, что все переменные лучше делать либо private, либо protected. Доступ к переменным должен осуществляться только за счёт методов и конструкторов. Доступ к полям напрямую должен быть закрыт.

Дополнительно создадим два объекта и выведем информацию:

public class Main < public static void main(String[] args) < Book sherlock_holms = new Book(460, 1.7f); // Используем 1 конструктор sherlock_holms.name = "Шерлок Холмс"; // Устанавливаем вручную значение для name sherlock_holms.getInfoBook (); Book green_mile = new Book(750, 2.8f, "Зеленая миля"); // Используем второй конструктор green_mile.getInfoBook (); >>

Поскольку переменная name имеет public модификатор доступа, то мы можем ссылаться к ней отдельно. Лучше так не делать и для неё тоже установить модификатор private.

Также конструктор может не принимать параметров. В таком случае при создании объекта ничего не надо дополнительно передавать.

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

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