Наследование Java - конструкторы

Во время учебы в финале, я наткнулся на следующее выражение в книге, из которой я сейчас изучаю. Учитывая следующий код:

class A {
    public A(int x) {   }
}

class B extends A {
    public B(int x ) {   }
}

необходимо вызвать конструктор класса A в конструкторе класса B (super (x)). В книге говорится, что это не обязательно, потому что у них есть точное количество и тип параметров. Но когда я пробую это в компиляторе java, возникает следующая ошибка:

конструктор A в классе A не может быть применяется к данным типам; обязательный: int found: нет аргументов аргумента: списки фактических и формальных аргументов отличаются длиной

Ответ 1

Компилятор автоматически вставляет super() в начало.

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

Вы должны указать super(x) (для вызова A(x)) или определить конструктор без аргументов.

Кстати, компилятор Eclipse дает лучшее сообщение об ошибке:

Неявный суперконструктор A() есть undefined. Необходимо явно вызвать другой конструктор

Ответ 2

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

required: int
found:    no arguments

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

В отличие от того, что написано в вашей книге (или в отличие от вашего понимания письменного текста), здесь предложение из спецификации языка:

Если тело конструктора не начинается с явного вызова конструктора и объявляемый конструктор не является частью первичного класса Object, тогда тело конструктора неявно предполагается компилятором, чтобы начать с супер вызов конструктора класса "super();" , вызов конструктора его прямой суперкласс, который не принимает аргументов.

Ответ 3

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

Но когда у вас есть конструктор с аргументами, при создании контрмера с параметрами в B вам нужно передать super() параметр для A

пример:

class A {
    public A(int x) {   }
  }

  class B extends A {
    public B(int x ) 
    {
       super(x); // need to specify the parameter for class A
       //... 
    }
  }

Ответ 4

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

Ответ 5

В случае Java необходимо вызвать конструктор суперкласса. Следовательно, всякий раз, когда вы создаете конструктор подкласса, конструктор суперкласса сам создается с помощью IDE.

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