В конструкторе, не имеющем тип возврата
Конструктор не должен иметь тип возвращаемого значения. По определению, если метод имеет тип возвращаемого значения, это не конструктор.
Конструктор используется при создании объекта, который является экземпляром класса. [Имя должно соответствовать имени класса, но] во всех других отношениях объявление конструктора выглядит так же, как объявление метода, у которого нет типа результата.
По умолчанию конструкторы
Следующий фрагмент кода выдает ошибку компиляции:
class Parent {
Parent(int a){}
}
class Child extends Parent{
// DOES NOT COMPILE!!
// Implicit super constructor parent() is undefined for default constructor.
// Must define an explicit constructor
}
Причина не в типе возвращаемого значения в конструкторе, а в том, что поскольку вы не предоставили конструктор ANY для Child
, автоматически создается конструктор default компилятором. Однако этот конструктор по умолчанию пытается вызвать конструктор по умолчанию суперкласса Parent
, который NOT имеет конструктор по умолчанию. ЭТО источник ошибки компиляции.
Вот спецификация для конструктора по умолчанию:
Если класс не содержит объявлений конструктора, автоматически предоставляется конструктор по умолчанию , который не принимает параметров:
- Если объявленный класс является первичным классом
Object
, то конструктор по умолчанию имеет пустое тело.
- В противном случае конструктор по умолчанию не принимает параметров и просто вызывает конструктор суперкласса без аргументов.
Ниже приведено простое исправление:
class Parent {
Parent(int a){}
}
class Child extends Parent{
// compiles fine!
Child() {
super(42);
}
}
О методах с тем же именем, что и у конструктора
Следующий фрагмент DOES compile:
// COMPILES FINE!!
class Parent {
// method has same name as class, but not a constructor
int Parent(int a) {
System.out.println("Yipppee!!!");
return 42;
}
// no explicit constructor, so default constructor is provided
}
class Child extends Parent {
// no explicit constructor, so default constructor is provided
}
На самом деле в приведенном фрагменте нет явного конструктора. У вас есть обычный метод с тем же именем, что и у класса. Это разрешено, но не рекомендуется:
A class
может объявить метод с тем же именем, что и class
или полем, членом class
или членом interface
класса, , но это не рекомендуется как вопрос стиля .
Вы обнаружите, что если вы создадите new Parent()
или new Child()
, "Yipppee!!!"
будет НЕ выводиться на стандартный вывод. Метод не вызывается при создании, поскольку он не является конструктором.