Зачем использовать конструкторы в абстрактных классах
Что проверяют
Понимаете ли вы порядок создания объекта в Java: абстрактный класс нельзя создать через new, но его конструктор всё равно выполняется. Следом обычно спрашивают, что будет, если вызвать абстрактный метод из конструктора.
Как отвечать
Любой конструктор наследника первым делом вызывает конструктор родителя, явно через super(...) или неявно без аргументов. Поэтому конструктор абстрактного класса нужен ровно для того же, для чего и у обычного: привести общую часть объекта в корректное состояние.
- общее состояние: поля, которые есть у всех наследников, инициализируются в одном месте, а не копируются по подклассам;
finalполя: присвоить их можно ровно один раз. Если значение приходит снаружи, сделать это можно только в конструкторе;- инварианты: проверка аргументов (
Objects.requireNonNull, допустимые диапазоны) в одном месте для всей иерархии; - обязательные параметры: если у абстрактного класса есть только конструктор с аргументами, наследник обязан вызвать
super(args), иначе код не скомпилируется. Так класс навязывает контракт создания; - видимость: конструктор обычно делают
protected, потому что вызывать его имеет смысл только наследникам.
Анонимный класс new Animal("Rex") { ... } тоже вызывает этот конструктор. У интерфейса конструкторов нет вообще, и это одно из ключевых отличий: интерфейс не хранит состояние экземпляра. В свежих версиях Java (гибкие тела конструкторов, JEP 513) до вызова super(...) разрешено проверить и подготовить аргументы, но читать поля и вызывать методы объекта там по-прежнему нельзя.
Где спотыкаются
Говорят, что у абстрактного класса конструктора быть не может, раз его нельзя инстанцировать. Может, и если вы его не написали, компилятор добавит конструктор по умолчанию.
Вызывают из конструктора абстрактный или переопределяемый метод. Он выполнится в наследнике до инициализации полей наследника и увидит null или 0.
Делают конструктор public и считают, что это что-то меняет. Создать экземпляр напрямую всё равно нельзя, а protected честнее описывает намерение.