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

Вызов super()

Когда вы вызываете super() в Java? Я вижу это в некоторых конструкторах производного класса, но не является ли конструктором для каждого родительского класса автоматически? Зачем вам нужно использовать супер?

4b9b3361

Ответ 1

Если вы предоставляете такой класс:

public class Foo
{
}

или это:

public class Foo()
{
    public Foo()
    {
    }
}

компилятор будет генерировать код для этого:

public class Foo()
{
    public Foo()
    {
        super();
    }
}

Итак, строго говоря, вызов "super()" всегда существует.

На практике вы должны вызывать только "super (...)", где есть параметры, которые вы хотите передать родительскому конструктору.

Неверно называть "super()" (без параметров), но люди будут смеяться над вами: -)

Ответ 2

Вам нужно использовать super() в таком случае:

public class Base {
   public Base(int foo) {
   }
}

public class Subclass extends Base {
   public Subclass() {
      super(15);
   }
}

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

Ответ 3

Нет необходимости вызывать super().

От Доступ к членам суперкласса:

С супер() вызывается конструктор без аргументов суперкласса. С супер (список параметров) вызывается конструктор суперкласса с соответствующим списком параметров.

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

Ответ 4

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

Так, как в ранее опубликованном коде

public class Foo
{
}

или

public class Foo
{
  public Foo()
  {
  }
}

компилятор будет генерировать код, который будет соответствовать правилам Java. Все объекты являются подклассами java.lang.Object, поэтому компилятор будет компилировать его, как если бы он был написан

// All classes extend Object.  This is Java, after all.
public class Foo extends java.lang.Object
{
  public Foo()
  {
    // When constructing Foo, we must call the Object() constructor or risk
    // some parts of Foo being undefined, like getClass() or toString().
    super()
  }
}

Но если суперкласс не имеет конструктора, который соответствует параметрам, тогда вы должны вызвать соответствующий несоответствующий конструктор суперклассов.

public class LightBlue extends java.awt.Color
{
  public LightBlue()
  {
    // There is no Color() constructor, we must specify the suitable super class
    // constructor.  We chose Color(int red, int green, int blue).
    super(172, 216, 230);
  }
}

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

public class HSVColor extends Color
{
  public HSVColor(int hue, int saturation, int value)
  {
    super(...code converting HSV to Red...,
          ...code converting HSV to Green...,
          ...code converting HSV to Blue);
  }
}

Если вы пренебрегаете явным определением конструктора суперкласса, компилятор добавляет в конструктор суперкласса no-arg по умолчанию. Однако, если этот конструктор не существует, компилятор не будет компилировать класс, потому что неясно, какой из открытых конструкторов является правильным для вызова.

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

Ответ 5

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

Однако явно вызов super() - это просто - явный. Если вы знаете, что конструктор суперкласса делает что-то значимое, это полезное напоминание о том, кто поддерживает ваш код, который сначала вызывает вызов super() (и может иметь побочные эффекты). Это может быть даже полезным местом для установки точки останова при отладке.

Ответ 6

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

class A
{   
    int a; 
    A(int value) 
    {
      this.a=value; 
      System.out.println("A Constructor " + a ); 
    }
}

class B extends A
{ 
    int b;
    B()
    {
      super(5);
      this.b=10; 
      System.out.println("B Constructor " + b); 
    } 

}

вы должны знать, что yo не может использовать "super" с "this", если вы хотите вызвать другой конструктор в calss с помощью "this".

Ответ 7

Я хотел предоставить некоторую информацию, которая пока не упоминалась. Если вы используете вызов в this(...) в конструкторе, вы не можете позвонить в super(...);. Это также включает автоматическую вставку безпараметрического вызова Java к super();

Следующий пример иллюстрирует этот момент, включая пояснительные комментарии:

public class B extends A {
    private int x;

    public B() {
        // Java doesn't call super(); here, because 
        // of the call to this(...); below.
        // You can't call super(...) here either,
        // for the same reason.

        this(42);  // Calls public B(int x) below.
    }

    public B(int x) {
        // Java does call super(); here.
        // You can call super(...) here, if you want/need to.
        // The net result of calling new B() above is that
        // super(...) for class A only gets called once.

        this.x = x;
    }
}

Ответ 8

super() неявно, когда не вызывается никакой другой конструктор класса/суперкласса.

Ответ 9

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

Ответ 10

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

public class DerivedClass extends SomeOtherClass
{
   private String anotherParameter;
   public DerivedClass(int parameterA, String parameterB, String anotherParameter)
   {
     super(parameterA, parameterB);
     this.anotherParameter = anotherParameter;
   }
}

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

Ответ 11

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

Прекрасным примером является создание Spring управляемых beans или JPA объектов, и вы создали параметризованный конструктор.

@Entity
public class Portfolio {

    ...

    public Portfolio() {
        super(); // This says to me: DON'T DELETE!
    }

    /**
    *  Because there is now a parameterised constructor (me), 
    *  the default constructor no longer exists. This means
    *  that for this example, you need an empty constructor in place (above) 
    **/
    public Portfolio(String name) {
        this.name = name;
    }
}

Ответ 12

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