Почему конструктор суперкласса вызывается, когда мы объявляем объект подкласса? (Джава) - PullRequest
34 голосов
/ 24 августа 2011

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

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);
    }
}

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

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

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

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

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

суммы 25

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

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

суммы 29

Ответы [ 18 ]

35 голосов
/ 24 августа 2011

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

см. 3.4.4 в здесь

19 голосов
/ 24 августа 2011

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

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

baseClassConstructor(){
    super(someParams);
}

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

baseClassConstructor(){
     foo(); 
     super(someParams); // compilation error
}
8 голосов
/ 18 мая 2016

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

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

enter image description here

3 голосов
/ 24 августа 2011

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

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

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

  1. создать локальные переменные для аргументов конструктора
  2. , если конструктор начинается с вызова другого конструктора для класса, вычислить аргументы и вернуться к предыдущему шагу.Все шаги для этого конструктора выполнены, включая дальнейшую рекурсию вызовов конструктора, прежде чем продолжить.
  3. , если суперкласс не был создан выше, создайте суперкласс (используя конструктор no-arg, если не указан).Как и в случае # 2, перед продолжением выполните все эти шаги для суперкласса, включая создание IT-суперкласса.
  4. инициализаторы для переменных экземпляра и нестатические блоки инициализатора, в порядке объявления.
  5. остальная часть конструктора.
2 голосов
/ 24 августа 2011

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

1 голос
/ 27 ноября 2016

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

1 голос
/ 08 сентября 2016

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

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

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

1 голос
/ 20 июня 2016

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

1 голос
/ 23 февраля 2016

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

 //Default constructor of subClass
    subClass() {
    super();
    }
1 голос
/ 20 ноября 2015

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...