Вызов супер () - PullRequest
       50

Вызов супер ()

28 голосов
/ 14 апреля 2010

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

Ответы [ 12 ]

44 голосов
/ 14 апреля 2010

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

public class Foo
{
}

или это:

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

компилятор сгенерирует код для этого:

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

Так что, строго говоря, вызов super () всегда есть.

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

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

23 голосов
/ 14 апреля 2010

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

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

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

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

2 голосов
/ 14 апреля 2010

Если вам не удалось вызвать 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);
  }
}

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

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

2 голосов
/ 14 апреля 2010

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

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

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

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

1 голос
/ 28 апреля 2014

Я хотел бы предоставить некоторую информацию, которая не была упомянута до сих пор. Если вы используете вызов 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;
    }
}
1 голос
/ 14 апреля 2010

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

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

}

Вы должны знать, что вы не можете использовать «super» с «this», если вы хотите вызвать другого конструктора в calss, используя «this».

1 голос
/ 14 апреля 2010

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

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

0 голосов
/ 26 августа 2016

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

0 голосов
/ 02 марта 2016

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

Прекрасным примером является то, что вы создаете управляемые компоненты Spring или объекты 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;
    }
}
0 голосов
/ 14 апреля 2010

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

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

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

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