Наследование в Java - создание объекта подкласса вызывает также конструктор суперкласса. Почему именно?
У меня вопрос о наследовании в Java.
У меня есть два класса A
и B
, а класс B, наследует от A:
public class A {
public A() {
System.out.println("Hi!");
}
}
public class B extends A {
public B() {
System.out.println("Bye!");
}
public static void main(String[] args) {
B b = new B();
}
}
Когда я запускаю программу B, вывод:
Hi!
Bye!
Вопрос: почему вызывается конструктор из class A
, когда я создаю и объект class B
?
Я знаю, что B наследует все от A - все переменные экземпляра или класса и все методы, и в этом смысле объект B имеет все характеристики A плюс некоторые другие характеристики, определенные в B. Однако я не знал и не предполагал, что когда я создаю объект типа B, также вызывается конструктор A.
Итак, пишу это:
B b = new B();
создает Два объекта - один из типов B и один из типов A.
Это становится интересным,
может кто-нибудь объяснить, почему именно это происходит?
Ответы
Ответ 1
Он не создает два объекта, только один: B.
При наследовании от другого класса вы должны вызвать super() в своем конструкторе. Если вы этого не сделаете, компилятор будет вставлять этот вызов для вас, как вы можете ясно видеть.
Конструкторы суперкласса вызываются, потому что иначе объект будет оставлен в неинициализированном состоянии, возможно, без ведома разработчика этого подкласса.
Ваш подкласс действительно выглядит так, как только компилятор вставляет супервызов:
public class B extends A {
public B() {
super();
System.out.println("Bye!");
}
}
Ответ 2
Он не создает 2 объекта, он создает только один экземпляр B. Причина, вызываемая конструктором суперкласса, заключается в том, что, как вы сказали, B имеет все поля A, и эти поля должны быть инициализированы.
Ответ 3
Помните, что наследование является отношением "является" между базовым классом и подклассом, поэтому каждый раз, когда у вас есть экземпляр подкласса, по определению у вас также будет экземпляр базового класса (как часть экземпляра, а не как два отдельных экземпляра). Для правильной инициализации базового класса вызывается конструктор.
Кроме того, подумайте о том, что произойдет, если ваш подкласс зависит от некоторого внутреннего состояния базового класса. Не хотите ли вы, чтобы экземпляр базового класса был инициализирован?
Ответ 4
Это делается потому, что конструктор используется для инициализации объекта. Поскольку B также является A, он сначала вызывает конструктор для A, тогда конструктор для B.
В качестве дополнительной заметки вы можете использовать super(arg1, etc)
, чтобы выбрать, какой конструктор A вызывается на основе типов параметров, которые вы передаете... но это должна быть первая строка в конструкторе.
Ответ 5
Он не создает два объекта, он просто создает один объект b. b имеет тип B и типа A. Конструктор в основном говорит, что вот что вам нужно сделать, чтобы построить меня. Поэтому, когда вы создаете новый экземпляр "B", вы строите объект, который является как B(), так и A(). Представьте себе следующий сценарий:
class Q {
int i;
public Q() {
// set default value
i= 99;
}
}
class Z extends Q {
public Z() {
}
}
Если конструктор для Q не был вызван, как бы получить его значение по умолчанию?
Ответ 6
Если A инициализирует члены в нем конструктором, и вы забываете называть super в производном классе, тогда члены A могут находиться в плохом состоянии. Java пытается помешать вам стрелять в ногу.
Ответ 7
Конструктор содержит всю инициализацию для A. Вы не создаете два объекта. Вы создаете один объект, а затем запускаете инициализатор для суперкласса для инициализации его членов, а затем запускаете инициализатор для класса вывода для инициализации его членов.
Ответ 8
Создан только один объект, оба подрядчика работают на одном и том же объекте.
Причина проста, так как вы знаете, что B имеет все переменные и методы A, поэтому, если какая-то переменная A нуждается в инициализации, так что методы A могут работать, кто-то должен ее инициализировать - и что кто-то является конструктором.
например:
public class A {
public A() {
x = 1;
}
private int x;
public int getX() {
return x;
}
}
public class B extends A {
public B() {
}
public static void main(String[] args) {
B b = new B();
System.out.println(b.getX()); // should print 1
}
}
Ответ 9
Создание B не создает дополнительного A.
Но создав B, вы создаете вид A, потому что B является A.
Java/С++ вызывает конструктор A для вашего неявно. Зачем? Языковой дизайн. Но делать это хорошо, потому что конструктор A может содержать некоторые инициализации. И поскольку B использует все функции и ошибки A, эти функции лучше инициализируются должным образом.
Ответ 10
Конструктор класса является очень важным понятием в большинстве ООП
Классы, предоставляя состояние и средства для управления этим состоянием, позволяют легче поддерживать инварианты. Роль конструкторов заключается в том, чтобы получить класс в состояние, которое соответствует этим инвариантам (или, таким образом, запрещает использование объекта invliad).
это несколько слабее, чем предполагалось на многих языках, поскольку конструктору разрешено передавать свою собственную ссылку 'this' в другом месте, но это по крайней мере находится под контролем класса (как таковой он может знать, что он находится в достаточно стабильном и действительном состоянии чтобы он был доступен для остального мира)
Наследование делает это сложным, так как B - это A в очень реальном смысле и поэтому может ссылаться на любой из методов, предоставляемых A. Части B, которые являются A, должны поэтому получить возможность инициализировать себя до того, как B будет выглядеть in, поэтому конструктор для A вызывается до начала реальной работы конструктора B.
Ответ 11
Когда создается новый объект (B), внутри B Создается объект (из-за расширений ключевых слов). В конструкторе класса B класса JVM B, но из-за расширений ключевых слов он переходит к суперклассическому конструктору. внутри Значение класса x инициализируется. Но x является частным, так что мы можем получить доступ к внешнему классу throw getXxx()
и получить результат.
Ответ 12
Когда создается объект подкласса, он внутренне не создан для объекта суперкласса. Но память должна быть выделена для членов суперкласса.
Ответ 13
В java, когда вы создаете объект дочернего класса, конструктор родительского класса всегда вызывается, потому что класс Object является родителем каждого суперкласса и когда вы вызываете конструктор класса Object, тогда создается только ваш объект, а java не поддерживать множественное наследование в случае класса, поэтому, если вы расширяете любой другой класс, тогда связь между вашим дочерним классом и классом Object осуществляется через класс родителя, поэтому для вызова конструктора класса Object должен быть вызван конструктор класса Parent.
Ответ 14
если объект суперкласса не создается, то как подкласс имеет доступ к нестационарным методам и переменным суперкласса.
Я изучил, что нестатические методы и переменные доступны только через объекты.