Конструкторы Java и super()

#java

#java

Вопрос:

Я видел несколько вопросов по этой теме, но все они предполагают знание наследования. Пример в моей книге приведен перед главой о наследовании, поэтому родительским классом является java.long.Объект.

1. Сценарий: в моем классе FotoApparat нет пользовательского конструктора или вообще какого-либо конструктора, и я создаю экземпляр FotoApparat с FotoApparat meinFotoApparat = new FotoApparat()

Вопрос: Поскольку в моем классе нет конструктора, а также нет вызова super(), я предполагаю, что программа проверяет класс родительского объекта на наличие подходящего конструктора, которым должен быть new Object(), верно? Если да, считается ли это все еще «неявным» вызовом super()?

2. Сценарий: я создаю пользовательский конструктор (с использованием источника eclipse), который принимает параметры. В сгенерированном конструкторе вызов super() добавляется в самом начале, который, как я предполагаю, является фактическим неявным вызовом, о котором я продолжаю читать. Я прочитал на javapoint, что при создании экземпляра класса также создается экземпляр родительского класса, на который ссылается super().

Вопрос: Я читал, что этот вызов super() может быть удален из конструктора, но если он удален, и я использую конструктор, который принимает параметры, то (без super()) как создается этот родительский объект ?!

Комментарии:

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

2. Под «а также без вызова space () » вы, возможно, имели в виду «а также без вызова super () «? (если нет, то не могли бы вы уточнить, что вы подразумеваете под space() вызовом)?

3. Да, извините, я улучшаю super()

Ответ №1:

Сценарий 1: Если вы не определяете какой-либо конструктор, для вас создается конструктор по умолчанию без аргументов. Это тот, который вызывается при использовании new FotoApparat() . Затем этот конструктор по умолчанию вызывает конструктор на Object (см. Сценарий 2.)

Сценарий 2: Если вы не вызываете явно super() , этот вызов все равно выполняется неявно. Однако возможно, что у родительского объекта нет конструктора без аргументов, и в этом случае вам потребуется вызвать определенный конструктор.

Ответ №2:

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

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

когда создается экземпляр класса, также создается экземпляр родительского класса

Не совсем: создается только один экземпляр. Отдельного экземпляра родительского класса не существует.

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

Я читал, что этот вызов super() может быть удален из конструктора, но если он удален, и я использую конструктор, который принимает параметры, то (без super()) как создается этот родительский объект ?!

В этом сценарии компилятор вставляет вызов конструктору суперкласса без аргументов super() . Но это не создает отдельный «родительский объект» — создается только один объект.

Что ваши исследования, возможно, не прояснили, так это различие между созданием объекта и инициализацией. Вызов конструктора не «создает» объект. Объект создается путем резервирования для него места в памяти. После того, как память была зарезервирована, вызывается конструктор для «инициализации» объекта.

Комментарии:

1. @Rick @Joni: Вы оба говорите, что если конструктора нет, компилятор создает его для меня — Вопрос: Я предполагаю, что это называется «время выполнения», правильно? Где создаются объекты, созданные во время выполнения? (например, скрытый файл или что-то в этом роде) Относительно создания и инициализации: если мы возьмем примитивный тип данных, создание (резервирование памяти) будет int number; , а инициализация будет int number = 123; . Если я правильно понимаю, эквивалентом этого для объектов является то, что new FotoApparat(); или этот неявный вызов super () резервирует только память?

2. И конструктор, который принимает параметры, тогда является инициализацией объекта, правильно? Когда инициализируется объект, если вы используете new FotoApparat() конструктор? Может быть, когда вы присваиваете значение одному из атрибутов?

3. Конструктор по умолчанию создается во время компиляции, а не во время выполнения. Это как если бы вы сами добавили это в исходный код. Что касается примитивных значений, таких как 7 или 3.14 или ‘S’, они просто существуют без необходимости их «создавать». Не путайте значения с переменными: переменные «создаются» при создании их контейнера. Переменные экземпляра создаются при создании экземпляра класса, локальные переменные создаются при вызове метода.

4. Запуск кода в конструкторе всегда инициализирует объект. Не имеет значения, является ли это конструктор без параметров по умолчанию, созданный компилятором, или тот, который вы написали сами. «Инициализировать» означает «установить поля в объекте в начальные значения, чтобы он мог использоваться остальной частью программы».