Основы Java: конструктор по умолчанию

Все классы Java имеют по крайней мере один конструктор, даже если мы не определяем его явно.

В этой статье мы рассмотрим поведение конструктора по умолчанию, которое иногда вызывает недоумение у новых Java-разработчиков.

Что такое конструктор по умолчанию?

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

Компилятор автоматически предоставляет общедоступный конструктор без аргументов для любого класса без конструкторов. Это называется конструктором по умолчанию.

Если мы явно объявим конструктор любой формы, то эта автоматическая вставка компилятором не произойдет.

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

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

public class MyClass { 
  // added by the compiler 
  public MyClass() { 
    super(); 
  } 
}

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

Пример

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

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

Мы определим суперкласс с именем Vehicle и расширим класс с помощью Car и Truck.

public class Vehicle { 
  protected String vin; 
  protected int modelYear; 
  public Vehicle(String vin) { 
    this.vin = vin; } 
  public Vehicle(String vin, int modelYear) { 
    this.vin = vin; this.modelYear = modelYear; 
  } 
}

Компилятор не будет вставлять конструктор по умолчанию в Vehicle, потому что мы определили пару конструкторов.

Наш подкласс с именем Car выглядит так:

public class Car extends Vehicle { }

Компилятор вставит конструктор по умолчанию в Car:

public class Car extends Vehicle { 
  public Car() { 
    super(); 
  } 
}

Метод super() относится к конструктору Vehicle без аргументов.

Проблема в том, что у Vehicle его нет, поэтому это приведет к следующей ошибке времени компиляции:

Implicit super constructor Vehicle() is undefined for default constructor. Must define an explicit constructor.

Чтобы решить эту проблему, мы должны добавить в Vehicle конструктор без аргументов:

public class Vehicle { 
  protected String vin; 
  protected int modelYear; 
  public Vehicle() { } 
  public Vehicle(String vin) { 
   this.vin = vin; } 
  public Vehicle(String vin, int modelYear) { 
    this.vin = vin; this.modelYear = modelYear; 
  } 
}

Первоначально опубликовано на www.codebyamir.com 2 октября 2017 г.