1. Обзор
В этом руководстве мы более подробно рассмотрим ошибку Java «неявный суперконструктор не определен» . Во-первых, мы создадим пример того, как его производить. Далее мы объясним основную причину исключения, а позже посмотрим, как это исправить.
2. Практический пример
Теперь давайте посмотрим на пример, который генерирует ошибку компиляции «Неявный суперконструктор X() не определен. Должен явно вызывать другой конструктор».
Здесь X
представляет родительский класс, который расширяется любым подклассом, который видит эту ошибку.
Во-первых, давайте создадим родительский класс Person
:
public class Person {
String name;
Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
// setters and getters
}
Теперь давайте создадим подкласс Employee
, родителем которого является Person
:
public class Employee extends Person {
Double salary;
public Employee(String name, Integer age, Double salary) {
this.salary = salary;
}
// setters and getters
}
Теперь в нашей IDE мы увидим ошибку:
Implicit super constructor Person() is undefined. Must explicitly invoke another constructor
В некоторых случаях мы можем получить аналогичную ошибку, если в дочернем классе нет конструктора.
Например, давайте рассмотрим Employee
без конструктора:
public class Employee extends Person {
Double salary;
// setters and getters
}
Мы увидим ошибку в нашей IDE:
Implicit super constructor Person() is undefined for default constructor. Must define an explicit constructor
3. Причина
В наследовании Java связывание конструкторов относится к вызову последовательности конструкторов с использованием суперметода
для связывания конструкторов из родительского класса. Конструкторы подкласса должны вызывать конструктор суперкласса явно или неявно. В любом случае должен быть определен суперконструктор.
Класс, у которого нет родителя, имеет класс Object
в качестве родителя. Класс Object
в Java имеет конструктор без аргументов.
Когда у класса нет конструктора, компилятор добавляет конструктор по умолчанию, не принимающий аргументов, и в первом операторе компилятор вставляет вызов super
, который вызывает конструктор класса Object
.
Предположим, что наш класс Person
не содержит конструктора и не имеет родителя. После компиляции мы видим, что компилятор добавил конструктор по умолчанию:
public Person() {
super();
}
Напротив, если в классе Person
уже есть конструктор , этот конструктор по умолчанию без аргументов не добавляется компилятором. ``
Теперь, если мы создадим подкласс Employee
, расширяющий Person,
мы получим ошибку в классе Employee
:
Implicit super constructor Person() is undefined for default constructor. Must define an explicit constructor
Поскольку компилятор вставит супервызов
конструктору Employee
, он не найдет конструктор без параметров в родительском классе Person.
4. Решение
Чтобы устранить эту ошибку, нам нужно явно предоставить информацию компилятору.
Первое, что нам нужно сделать, это явно вызвать суперконструктор
из конструктора Employee
:
public Employee(String name, Integer age, Double salary) {
super(name, age);
this.salary = salary;
}
Теперь предположим, что нам нужно создать объект Employee
только с полем зарплаты .
Напишем конструктор:
public Employee(Double salary) {
super();
this.salary = salary;
}
Несмотря на добавление вызова super в конструктор
Employee
, мы все равно получаем ошибку, потому что в классе Person
по- прежнему отсутствует соответствующий конструктор . Мы можем исправить это, явно создав конструктор без аргументов в классе Person
:
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public Person() {
}
Наконец, благодаря этим изменениям мы не получим ошибок компиляции.
5. Вывод
Мы объяснили ошибку Java «неявный суперконструктор не определен». Затем мы обсудили, как создать ошибку и причину исключения. Наконец, мы обсудили решение для устранения ошибки.
Как всегда, пример кода для этой статьи доступен на GitHub .