Подтвердить что ты не робот

Почему конструктор суперкласса вызывается, когда мы объявляем объект подкласса? (Ява)

Рассмотрим этот код:

class Test {
    Test() {
        System.out.println("In constructor of Superclass");
    }

    int adds(int n1, int n2) {
        return(n1+n2);
    }

    void print(int sum) {
        System.out.println("the sums are " + sum);
    }
}


class Test1 extends Test {
    Test1(int n1, int n2) {
        System.out.println("In constructor of Subclass");
        int sum = this.adds(n1,n2);
        this.print(sum);
    }

    public static void main(String[] args) {
        Test1 a=new Test1(13,12);
        Test c=new Test1(15,14);
    }
}

Если у нас есть конструктор в суперклассе, он будет вызываться каждым объектом, который мы создаем для дочернего класса (например, Object a для класса Test1 вызывает Test1(int n1, int n2) а также его родительский Test()),

Почему это происходит?

Выход этой программы:

В конструкторе Суперкласса

В конструкторе подкласса

суммы 25

В конструкторе Суперкласса

В конструкторе подкласса

суммы 29

4b9b3361

Ответ 1

Поскольку он будет гарантировать, что при вызове конструктора он может полагаться на все поля в своем суперклассе, который будет инициализирован.

см. 3.4.4 в здесь

Ответ 2

Да. Суперкласс должен быть создан до того, как может быть создан производный класс, в противном случае некоторые поля, которые должны быть доступны в производном классе, могут быть не инициализированы.

Небольшое примечание: если вам нужно явно вызвать конструктор суперкласса и передать ему некоторые параметры:

baseClassConstructor(){
    super(someParams);
}

тогда супер-конструктор должен быть первым вызовом метода в производном конструкторе. Например, это не скомпилируется:

baseClassConstructor(){
     foo(); 
     super(someParams); // compilation error
}

Ответ 3

super() добавляется в каждый конструктор класса автоматически компилятором.

Как мы хорошо знаем, конструктор по умолчанию предоставляется компилятором автоматически, но он также добавляет super() для первого оператора. Если вы создаете свой собственный конструктор, и у вас нет this() или super() в качестве первого оператора, компилятор предоставит super() в качестве первого оператора конструктора.

enter image description here

Ответ 4

Java-классы создаются в следующем порядке:

(при загрузке по времени)  0. инициализаторы для статических элементов и статических блоков инициализатора, чтобы   декларации.

(у каждого нового объекта)

  • создавать локальные переменные для аргументов конструктора
  • если конструктор начинается с вызова другого конструктора для класс, оценить аргументы и вернуться к предыдущему шагу. Все шаги для этого конструктора завершены, включая дальнейшую рекурсию вызовы конструктора, прежде чем продолжить.
  • если суперкласс не был построен выше, постройте суперкласс (используя конструктор no-arg, если он не указан). Как 2, выполните все эти шаги для суперкласса, включая построение ИТ-суперкласс, прежде чем продолжить.
  • инициализаторы для переменных экземпляра и нестатические блоки инициализатора, в порядок декларации.
  • остальная часть конструктора.

Ответ 5

Вот как работает Java. Если вы создаете дочерний объект, супер конструктор (неявно) называется.

Ответ 6

Подкласс наследует поля из этого суперкласса (es), и эти поля должны быть построены/инициализированы (что обычная цель конструктора: инициализировать члены класса, чтобы экземпляр работал по мере необходимости. Мы знаем, что некоторые люди, но больше функциональности у этих плохих конструкторов...)

Ответ 7

Конструктор реализует логику, которая делает объект готовым к работе. Объект может содержать состояние в закрытых полях, поэтому доступ к ним могут только методы его класса. Поэтому, если вы хотите, чтобы экземпляр вашего подкласса был действительно готов работать после вызова конструктора (т.е. Все его функциональные возможности, включая унаследованные от базового класса, в порядке), должен быть вызван конструктор базового класса.

Вот почему система работает именно так.

Вызывается автоматически конструктор по умолчанию базового класса. Если вы хотите изменить это, вы должны явно вызвать конструктор базового класса, написав super() в первой строке конструктора вашего подкласса.

Ответ 8

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

Ответ 9

Когда мы создаем объект подкласса, он должен учитывать все функции-члены и переменные-члены, определенные в суперклассе. Может возникнуть случай, когда какая-либо переменная-член может быть инициализирована в некоторых конструкторах суперкласса. Следовательно, когда мы создаем объект подкласса, все конструкторы в соответствующем дереве наследования вызываются в верхнем дне.

В частности, когда переменная определяется как защищенная, она всегда будет доступна в подклассе независимо от того, находится ли подкласс в одном пакете или нет. Теперь из подкласса, если мы вызываем функцию суперкласса для печати значения этой защищенной переменной (которая может быть инициализирована в конструкторе суперкласса), мы должны получить правильное инициализированное значение. Если все конструкторы суперкласса вызывают.

Внутренне Java вызывает super() в каждом конструкторе. Поэтому каждый конструктор подкласса называет его конструктором суперкласса, используя super(), и, следовательно, они выполняются в верхнем дне.

Примечание. Функции можно переопределить, а не переменные.

Ответ 10

Поскольку вы наследуете свойства базового класса в производный класс, могут возникнуть ситуации, когда ваш конструктор производного класса требует, чтобы некоторые из переменных базового класса инициализировали свои переменные. Поэтому сначала он должен инициализировать переменные базового класса, а затем производные переменные класса. Поэтому Java вызывает первый конструктор базового класса, а затем производный конструктор класса.

И также не имеет смысла инициализировать дочерний класс без инициализации родительского класса.

Ответ 11

Конструктор класса Super в первом вызове, потому что все методы в программе, которые сначала присутствуют в куче и после компиляции, сохраняются в стеке, из-за чего сначала создается конструктор суперклассов.

Ответ 12

В простых словах, если суперкласс имеет параметризованный конструктор, вам нужно явно вызвать super (params) в первой строке вашего конструктора дочернего класса, иначе неявно все конструкторы суперклассов будут названы до тех пор, пока класс объекта не будет повторно.

Ответ 13

В стандартных конструкторах подклассов по умолчанию используется супер() по умолчанию.

 //Default constructor of subClass
    subClass() {
    super();
    }

Ответ 14

"Если конструктор явно не вызывает конструктор суперкласса, компилятор Java автоматически вставляет вызов конструктору без аргумента суперкласса. Если у суперкласса нет конструктора без аргументов, вы получите компиляцию -time error. У объекта есть такой конструктор, поэтому, если Object является единственным суперклассом, проблем нет."
(источник: https://docs.oracle.com/javase/tutorial/java/IandI/super.html)

Ответ 15

Я постараюсь ответить на это с другой точки зрения.

Предположим, что Java не вызывал супер конструктор для вас автоматически. Если вы наследуете класс, вам придется либо вызвать супер конструктор неявно, либо переписать его самостоятельно. Это потребует от вас внутреннего знания о том, как работает суперкласс, что плохо. Также потребовалось бы переписать код, что тоже не очень хорошо.

Я согласен, что вызов супер-конструктора за кулисами немного неинтуитивно. С другой стороны, я не уверен, как они могли бы сделать это более интуитивно.

Ответ 16

Как известно, переменные-члены (поля) класса должны быть инициализированы перед созданием объекта, потому что эти поля представляют состояние объекта. Если эти поля явно не инициализированы, компилятор неявно предоставляет их значения по умолчанию, вызывая конструктор по умолчанию без аргументов. Вот почему конструктор subclass вызывает конструктор по умолчанию без аргумента суперкласса или неявно вызывается компилятором. Локальные переменные не предоставляются значениями по умолчанию компилятором.

Ответ 17

здесь ваш расширенный тест для вашего класса test1 означает, что вы можете получить доступ ко всем методам и переменной теста в вашем test1. учтите, что u может обращаться к методам или переменной класса только в том случае, если для нее выделена память, и для этого ему нужен какой-либо конструктор либо по умолчанию, либо параметризован, поэтому здесь, когда компилятор обнаруживает, что он расширяет класс, он попытается найти суперкласс, чтобы u мог получить доступ ко всем его методам.

Ответ 18

Родители выходят первым! И как реальный мир Ребенок не может существовать без Родителей. Поэтому сначала инициализация родителей (SuperClass) важна для использования классов в классах детей (подкласс).