Наследование в Java – создание объекта подclassа вызывает также конструктор суперclassа. Почему именно?

У меня вопрос о наследовании на Java.

У меня есть два classа A и B и class 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 – все переменные экземпляра или classа и все методы, и в этом смысле объект B имеет все характеристики A плюс некоторые другие характеристики, определенные в B. Однако я не знал и не знал, Представьте себе, что когда я создаю объект типа B, также вызывается конструктор A. Итак, написав это:

 B b = new B(); 

создает два объекта – один из типов B и один из типов A.

Это становится интересным,

может кто-нибудь объяснить, почему именно это происходит?

    Он не создает два объекта, только один: B.

    При наследовании от другого classа вы должны вызвать super () в своем конструкторе. Если вы этого не сделаете, компилятор будет вставлять этот вызов для вас, как вы можете ясно видеть.

    Конструкторы суперclassа вызываются, потому что иначе объект будет оставлен в неинициализированном состоянии, возможно, без ведома разработчика этого подclassа.

    Ваш подclass действительно выглядит так, как только компилятор вставляет супервызов:

     public class B extends A { public B() { super(); System.out.println("Bye!"); } } 

    Он не создает 2 объекта, он создает только один экземпляр B. Причина, по которой вызывается конструктор суперclassа, состоит в том, что, как вы сказали, B имеет все поля A, и эти поля должны быть инициализированы.

    Помните, что наследование является «отношением» между базовым classом и подclassом, поэтому каждый раз, когда у вас есть экземпляр подclassа, по определению у вас также будет экземпляр базового classа (как часть экземпляра, а не как два отдельные экземпляры). Для правильной инициализации базового classа вызывается конструктор.

    Кроме того, подумайте о том, что произойдет, если ваш подclass зависит от некоторого внутреннего состояния базового classа. Не хотите ли вы, чтобы экземпляр базового classа был инициализирован?

    Это делается потому, что конструктор используется для инициализации объекта. Так как B также является A, он сначала вызывает конструктор для A, тогда конструктор для B.

    В качестве дополнительной заметки вы можете использовать super(arg1, etc) Чтобы выбрать, какой конструктор A вызывается на основе типов параметров, которые вы передаете … но это должна быть первая строка в конструкторе.

    Он не создает два объекта, он просто создает один объект 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 не был вызван, как бы получить его значение по умолчанию?

    Если A выполняет инициализацию членов в его конструкторе, и вы забываете называть super в производном classе, тогда члены A могут находиться в плохом состоянии. Java пытается помешать вам стрелять в ногу.

    Конструктор содержит всю инициализацию для A. Вы не создаете два объекта. Вы создаете один объект, а затем запускаете инициализатор для суперclassа для инициализации его членов, а затем запускаете инициализатор для classа получения для инициализации его элементов.

    Создается только один объект, оба подрядчика работают на одном объекте.

    Причина проста, так как вы знаете, что B имеет все переменные и методы A, поэтому, если какая-либо переменная 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 } } 

    Создание B не создает дополнительного A.

    Но, создав B, вы создаете вид A, потому что B является A.

    Java / C ++ вызывает конструктор A для вашего неявно. Зачем? Языковой дизайн. Но делать это хорошо, потому что конструктор A может содержать некоторые инициализации. И поскольку B использует все функции и ошибки A, эти функции лучше инициализируются должным образом.

    Конструктор classа является очень важным понятием в большинстве ООП

    Классы, предоставляя состояние и средства для манипулирования этим состоянием, позволяют легче поддерживать инварианты. Роль конструкторов заключается в том, чтобы получить class в состояние, которое соответствует этим инвариантам (или, таким образом, запрещает использование объекта invliad). это несколько слабее, чем предполагалось на многих языках, поскольку конструктору разрешено передавать свою собственную «эту» ссылку в другом месте, но это по крайней мере находится под контролем classа (как таковой он может знать, что он находится в достаточно стабильном и действительном состоянии чтобы он был доступен для остального мира)

    Наследование делает это сложным, так как B – это A в очень реальном смысле и поэтому может ссылаться на любой из методов, предоставляемых A. Части B, которые являются A, должны поэтому получить возможность инициализировать себя до того, как B заглянет, таким образом конструктор для A вызывается до начала реальной работы конструктора B.

    Когда создается новый объект (B), создается внутренний объект BA (из-за расширений ключевых слов). В конструкторе classа B classа JVM B, но из-за расширений ключевых слов он переходит к суперclassическому конструктору. внутри Значение classа x инициализируется. Но x является частным, так что мы можем получить доступ к getXxx() classа вне classа и получить результат.

    Когда объект подclassа создается, а внутри он не был создан для объекта суперclassа. Но память должна быть выделена для членов суперclassа.

    В java, когда вы создаете объект дочернего classа, конструктор родительского classа всегда вызывается, потому что class Object является родителем каждого суперclassа, а когда вы вызываете конструктор classа Object, тогда создается только ваш объект и java не поддерживает множественное наследование в случае classа, поэтому, если вы расширяете любой другой class, тогда связь между вашим дочерним classом и classом Object осуществляется через class родителя, поэтому для вызова конструктора classа Object должен быть вызван конструктор classа Parent.

    Каждый суперclass имеет конструктор, и каждый конструктор иерархии запускается во время создания объекта подclassа.

    если объект суперclassа не создается, то как подclass выполняет доступ к нестационарным методам и переменным суперclassа.

    Я изучил, что нестатические методы и переменные могут быть доступны только через объекты.

    Давайте будем гением компьютера.