Конструкторы по умолчанию и наследование в Java - PullRequest
51 голосов
/ 08 февраля 2009

У меня есть вопрос о конструкторах по умолчанию и наследовании в Java.

Как правило, если вы пишете класс и не включаете никакого конструктора, Java автоматически предоставляет вам конструктор по умолчанию (один без параметров), который инициализирует все переменные экземпляра класса (если они есть) с некоторыми значениями по умолчанию ( 0, ноль или ложь). Однако если вы пишете конструктор с некоторыми параметрами и не пишете конструктора по умолчанию, то Java не предоставляет конструктор по умолчанию. Мой вопрос: как обстоят дела с классами, которые наследуются от других классов - если я напишу конструктор с некоторыми параметрами в них, но не включу конструктор по умолчанию, они наследуют конструктор по умолчанию суперкласса?

Ответы [ 11 ]

61 голосов
/ 09 февраля 2009
  1. Если вы не создаете конструктор, автоматически создается пустой конструктор по умолчанию .

  2. Если какой-либо конструктор явно не вызывает super или этот конструктор в качестве первого оператора, автоматически добавляется вызов super () .

Всегда.

52 голосов
/ 08 февраля 2009

Конструкторы не наследуются.

Кроме того, инициализация полей выполняется виртуальной машиной, а не конструктором по умолчанию. Конструктор по умолчанию просто вызывает конструктор по умолчанию для суперкласса, а конструктор по умолчанию для Object является пустым. Хорошая особенность этого дизайна в том, что нет способа получить доступ к неинициализированным полям.

11 голосов
/ 08 февраля 2009

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

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

6 голосов
/ 29 ноября 2012

Основное правило - вызов (или вызов) конструктора должен быть первым оператором, который должен выполнить JVM,

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

5 голосов
/ 13 февраля 2015

Раздел 8.8.9 Спецификации языка Java подробно объясняет, что происходит:

Если класс не содержит объявлений конструктора, то конструктор по умолчанию неявно объявлено. Форма конструктора по умолчанию для класса верхнего уровня, класс члена или локальный класс выглядит следующим образом:

  • Конструктор по умолчанию имеет ту же доступность, что и класс (§6.6).
  • Конструктор по умолчанию не имеет формальных параметров, кроме как не закрытых внутренний класс-член, где конструктор по умолчанию неявно объявляет один формальный параметр, представляющий непосредственно включающий экземпляр класса (§8.8.1, §15.9.2, §15.9.3).
  • Конструктор по умолчанию не имеет предложений throws.
  • Если объявленный класс является первичным классом Object, то по умолчанию Конструктор имеет пустое тело. В противном случае конструктор по умолчанию просто вызывает конструктор суперкласса без аргументов.

Вы можете видеть, что здесь не происходит наследование: все, что нужно для этого - это "магия компилятора" с неявно объявленным конструктором по умолчанию. Спецификация также поясняет, что конструктор по умолчанию добавляется только тогда, когда у класса вообще нет конструкторов, что означает, что ответом на ваш вопрос является «нет»: как только вы дадите классу конструктор, доступ к конструктору по умолчанию его суперкласс потерян.

3 голосов
/ 08 февраля 2009

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

Конструктор по умолчанию не инициализирует ваши личные переменные значениями по умолчанию. Доказательством является то, что можно написать класс, который не имеет конструктора по умолчанию и имеет закрытые члены, инициализированные значениями по умолчанию. Вот пример:

public class Test {

    public String s;
    public int i;

    public Test(String s, int i) {
        this.s = s;
        this.i = i;
    }

    public Test(boolean b) {
        // Empty on purpose!
    }

    public String toString() {
        return "Test (s = " + this.s + ", i = " +  this.i + ")";
    }

    public static void main (String [] args) {
        Test test_empty = new Test(true);
        Test test_full = new Test("string", 42);
        System.out.println("Test empty:" + test_empty);
        System.out.println("Test full:"  + test_full);
    }
}
2 голосов
/ 23 марта 2017

Ответ на ваш вопрос очень прост. Неявно (невидимо), первое утверждение в любом конструкторе является 'super ();' то есть вызов конструктора без параметров суперкласса, пока вы явно не измените его на что-то вроде 'this ();', this (int) ',' this (String) ',' super (int) ',' super (String )' так далее. 'этот();' является конструктором текущего класса.

2 голосов
/ 23 июня 2011

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

1 голос
/ 30 августа 2017

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

1 голос
/ 26 января 2011

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

...