← Назад к вопросам

Предсказать вывод: абстрактный класс с конструктором

1.0 Junior🔥 91 комментариев
#Другое#Основы Java

Условие

Какой результат выведет следующий код?

public abstract class OurAbstractClass {
   public OurAbstractClass() {
      System.out.println("This is abstract class constructor");
   }
}

class OurDemoClass extends OurAbstractClass {
   public OurDemoClass() {
      System.out.println("This is demo class constructor");
   }
   
   public static void main(String[] args) {
      OurDemoClass ourDemoClass = new OurDemoClass();
   }
}

Вопросы

  1. Что выведет программа?
  2. В каком порядке вызываются конструкторы?
  3. Можно ли создать экземпляр абстрактного класса напрямую?

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Предсказание вывода: абстрактный класс с конструктором

Результат выполнения

Программа выведет:

This is abstract class constructor
This is demo class constructor

Почему так?

Это классический пример иерархии конструкторов в наследовании. При создании объекта дочернего класса Java автоматически вызывает конструктор родительского класса.

Порядок вызова конструкторов

  1. Сначала конструктор родителя (OurAbstractClass) — выводит "This is abstract class constructor"
  2. Потом конструктор дочернего класса (OurDemoClass) — выводит "This is demo class constructor"

Это происходит, потому что компилятор Java автоматически добавляет вызов super() в конструктор дочернего класса:

class OurDemoClass extends OurAbstractClass {
   public OurDemoClass() {
      super();  // ← вызов конструктора родителя (компилятор добавляет автоматически)
      System.out.println("This is demo class constructor");
   }
}

Механизм наследования конструкторов

Правило: Конструктор дочернего класса ВСЕГДА вызывает конструктор родительского класса в начале своего выполнения (явно или неявно).

// ❌ Неправильно (скрытый вызов super())
public class Child extends Parent {
    public Child() {
        System.out.println("Child constructor");
    }
}

// ✓ Эквивалентно (явный вызов super())
public class Child extends Parent {
    public Child() {
        super();  // явно
        System.out.println("Child constructor");
    }
}

Важный факт: абстрактный класс имеет конструктор

Вопрос: Можно ли создать объект абстрактного класса напрямую?

// ❌ ОШИБКА! Нельзя инстанцировать абстрактный класс напрямую
OurAbstractClass obj = new OurAbstractClass();  // Compilation error

// ✓ Можно через дочерний класс
OurDemoClass obj = new OurDemoClass();  // OK!

Но! Конструктор абстрактного класса всё равно существует и выполняется при создании дочерних объектов.

Визуализация процесса

Операция: new OurDemoClass()

├─ Начало инициализации объекта
├─ Вызов super() (явно или неявно)
│  └─ Выполнение OurAbstractClass() → выводит сообщение
├─ Выполнение OurDemoClass() → выводит сообщение
└─ Конец инициализации

Пример с явным вызовом super()

public abstract class OurAbstractClass {
   public OurAbstractClass() {
      System.out.println("Abstract class constructor");
   }
}

class OurDemoClass extends OurAbstractClass {
   public OurDemoClass() {
      super();  // явный вызов конструктора родителя
      System.out.println("Demo class constructor");
   }
}

public class Main {
   public static void main(String[] args) {
      OurDemoClass obj = new OurDemoClass();
   }
}

/* Вывод:
Abstract class constructor
Demo class constructor
*/

Цепочка наследования (многоуровневое)

public abstract class GrandParent {
   public GrandParent() {
      System.out.println("1. GrandParent");
   }
}

public abstract class Parent extends GrandParent {
   public Parent() {
      System.out.println("2. Parent");
   }
}

public class Child extends Parent {
   public Child() {
      System.out.println("3. Child");
   }
}

public class Main {
   public static void main(String[] args) {
      new Child();
   }
}

/* Вывод:
1. GrandParent
2. Parent
3. Child
*/

Каждый уровень вызывает super() перед своим конструктором!

С параметрами в конструкторах

public abstract class OurAbstractClass {
   public OurAbstractClass(String msg) {
      System.out.println("Abstract: " + msg);
   }
}

class OurDemoClass extends OurAbstractClass {
   public OurDemoClass(String msg) {
      super(msg);  // передаём параметры родителю
      System.out.println("Demo: " + msg);
   }
}

public class Main {
   public static void main(String[] args) {
      new OurDemoClass("Hello");
   }
}

/* Вывод:
Abstract: Hello
Demo: Hello
*/

Порядок инициализации объекта в Java

1. Выделение памяти для объекта
2. Инициализация полей класса (значения по умолчанию)
3. Вызов конструктора:
   3.1. Неявный вызов super() (если не указан явно)
   3.2. Инициализация блоков инициализации
   3.3. Выполнение тела конструктора

Инициализационные блоки

public abstract class OurAbstractClass {
   {
      System.out.println("Abstract init block");
   }
   
   public OurAbstractClass() {
      System.out.println("Abstract constructor");
   }
}

class OurDemoClass extends OurAbstractClass {
   {
      System.out.println("Demo init block");
   }
   
   public OurDemoClass() {
      System.out.println("Demo constructor");
   }
}

/* Вывод:
Abstract init block      // инициализационный блок родителя
Abstract constructor     // конструктор родителя
Demo init block          // инициализационный блок дочернего класса
Demo constructor         // конструктор дочернего класса
*/

Различие между static инициализацией и конструктором

public abstract class OurAbstractClass {
   static {
      System.out.println("Abstract static block (один раз при загрузке класса)");
   }
   
   {
      System.out.println("Abstract instance block (каждый раз при создании объекта)");
   }
   
   public OurAbstractClass() {
      System.out.println("Abstract constructor");
   }
}

class OurDemoClass extends OurAbstractClass {
   static {
      System.out.println("Demo static block (один раз при загрузке класса)");
   }
   
   {
      System.out.println("Demo instance block");
   }
   
   public OurDemoClass() {
      System.out.println("Demo constructor");
   }
}

/* Вывод при первом new OurDemoClass():
Abstract static block
Demo static block
Abstract instance block
Abstract constructor
Demo instance block
Demo constructor

Вывод при втором new OurDemoClass():
Abstract instance block
Abstract constructor
Demo instance block
Demo constructor
*/

Ключевые выводы

Абстрактный класс может иметь конструктор — он будет вызван при создании дочернего объекта

Нельзя создавать экземпляры абстрактного класса напрямую, но его конструктор выполняется через наследование

Порядок: всегда сначала родитель, потом дочерний класс

Super() добавляется автоматически, если не указан явно

Инициализационные блоки выполняются до конструктора

Static блоки выполняются один раз при загрузке класса, не при каждом создании объекта

Вывод

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

Предсказать вывод: абстрактный класс с конструктором | PrepBro