class a{
a(int age){}
}
class b extends a{}
public class HelloWorld {
public static void main(String[] args) {
b var1=new b();
System.out.println("Try programiz.pro");
}
}
приведенный выше код не работает. Если я включаю оператор super(10) в конструктор дочернего класса, он работает.
но без какого-либо конструктора он работает, как показано ниже
class a{}
class b extends a{}
public class HelloWorld {
public static void main(String[] args) {
b var1=new b();
System.out.println("Try programiz.pro");
}
}
если это потому, что мы должны указать конструктор суперкласса по умолчанию во втором коде, мы не указали конструктор, и он все равно работает. Можете ли вы объяснить, почему?
Первая строка конструктора подкласса должна быть вызовом конструктора суперкласса. Если конструктор подкласса не вызывает явно конструктор суперкласса, компилятор Java автоматически включает вызов конструктора суперкласса с нулевыми аргументами. Если такого конструктора нет, это приводит к ошибке времени компиляции. Это именно то, что вы описываете, и что происходит с кодом, как в вашем примере.
Прочтите это для получения дополнительной информации о super()
и конструкторах подклассов.
В Java компилятор вставляет конструктор по умолчанию тогда и только тогда, когда для класса не определен явный конструктор. Этот конструктор по умолчанию:
Именно этот последний момент и объясняет, почему ваш первый пример кода не компилируется. В вашем классе A
определен явный конструктор с одним параметром, поэтому у него нет конструктора с нулевым параметром, который можно было бы вызвать из конструктора по умолчанию подкласса B
.
Когда у тебя есть:
public class A {
// Explicit constructor
public A(int arg) {}
}
public class B extends A {}
Это то же самое, что написать:
public class A extends Object {
// Note: No default constructor.
// Explicit constructor
public A(int arg) {
super(); // OKAY: The 'Object' class has a no-arg constructor.
}
}
public class B extends A {
// Default constructor
public B() {
super(); // ERROR: The 'A' class does not have a no-arg constructor.
}
}
Когда у тебя есть:
public class A {}
public class B extends A {}
Это то же самое, что написать:
public class A extends Object {
// Default constructor
public A() {
super(); // OKAY: The 'Object' class has a no-arg constructor.
}
}
public class B extends A {
// Default constructor
public B() {
super(); // OKAY: The 'A' class has a no-arg constructor.
}
}
2
1. See §8.8.7. Constructor Body and §8.8.9. Default Constructor of the Java Language Specification.
Конструкторы предназначены для инициализации класса в четко определенном состоянии. Вы предоставили A
явный конструктор, который принимает int
в качестве аргумента. Очевидно, что int
важен для логики инициализации. Итак, как в этом случае компилятор должен реализовать конструктор по умолчанию? Он понятия не имеет, для чего нужен этот аргумент и какое значение он должен передать. Разработчик не просто так написал явный конструктор с аргументами; если конструктор без аргументов должен существовать рядом с параметризованным конструктором(ами), то его написание остается на усмотрение разработчика. Так безопаснее.
Обратите внимание, что это поведение определяется спецификацией языка Java. Я добавил ссылки на свой ответ.
Java не может вставить его, потому что так говорит JLS. Именно так была определена Java... еще в 1990-х годах... и дизайнеры (предположительно) не увидели и не услышали веской причины изменить это. И я не могу придумать веской (не говоря уже о убедительной) причине изменить это. И есть веские причины НЕ делать этого... связанные с границами абстракции.
почему Java не может вставить конструктор без аргументов в первом случае?