Коли я використовую super ()?


82

На даний момент я вивчаю успадкування класів у своєму курсі Java, і я не розумію, коли використовувати super()виклик?

Редагувати:
я знайшов цей приклад коду, де використовується:super.variable

class A
{
    int k = 10;
}

class Test extends A
{
    public void m() {
        System.out.println(super.k);
    }
}

Тому я розумію, що тут ви повинні використовувати superдля доступу до kзмінної в супер-класі. Однак у будь-якому іншому випадку, що super();робити? Самотужки?


31
Власне, у цьому прикладі superпосилання не вимагається k. kна них можна посилатися безпосередньо. superдоступ буде необхідний лише у A.kвипадку, якщо ви оголосили інше поле з іменем kу Test( Test.k).
Марк Пітерс

Відповіді:


143

Виклик саме super() це завжди надлишкова. Це явно робить те, що було б неявно зроблено інакше. Це тому, що якщо ви пропустите виклик суперконструктора, суперконструктор no-argument все одно буде викликаний автоматично. Не сказати, що це поганий стиль; Деякі люди люблять бути явними.

Однак де це стає корисним, коли суперконструктор бере аргументи, які ви хочете передати з підкласу.

public class Animal {
   private final String noise;
   protected Animal(String noise) {
      this.noise = noise;
   }

   public void makeNoise() {
      System.out.println(noise);
   }
}

public class Pig extends Animal {
    public Pig() {
       super("Oink");
    }
}

2
Припустимо, метод перевизначений у дочірньому класі, а потім знову замінений у своєму дочірньому класі. (Багаторівневе успадкування) Що робити, якщо нам доведеться одночасно викликати метод дідуся і батька в клас онуків. Як би використовувався супер?
h8pathak

2
@ h8pathak: Якщо ви запитуєте, як дочірній клас може обійти реалізацію свого батька, але зателефонувати бабусі та дідусю, це неможливо в Java.
Mark Peters

44

superвикористовується для виклику constructor, methodsі propertiesбатьківського класу.


23

Ви також можете використовувати superключове слово в підкласі, коли ви хочете викликати метод з батьківського класу, коли ви його замінили в підкласі.

Приклад:

public class CellPhone {
    public void print() {
        System.out.println("I'm a cellphone");
    }
}

public class TouchPhone extends CellPhone {
    @Override
    public void print() {
        super.print();
        System.out.println("I'm a touch screen cellphone");
    }
    public static void main (strings[] args) {
        TouchPhone p = new TouchPhone();
        p.print();
    }
}

Тут рядок super.print()викликає print()метод суперкласу CellPhone. Результатом буде:

I'm a cellphone
I'm a touch screen cellphone

1
це було (String [] args) у вашому головному рядку оголошення методу? Дуже дякую!
Аппалачська математика

9

Коли ви хочете викликати конструктор суперкласу - ініціалізувати поля всередині нього. Погляньте на цю статтю, щоб зрозуміти, коли її використовувати:

http://download.oracle.com/javase/tutorial/java/IandI/super.html


4
Як сказано в посиланні, вам ніколи не доведеться телефонувати super(), оскільки Java неявно додасть його. Але вам потрібно зателефонувати, super(args)якщо вам потрібен батьківський конструктор, який не є типовим.
Майкл Брюер-Девіс

9

Ви можете використовувати його як перший рядок конструктора підкласу для виклику конструктора його батьківського класу.

Наприклад:

public class TheSuper{
    public TheSuper(){
        eatCake();
    }
}

public class TheSub extends TheSuper{
    public TheSub(){
        super();
        eatMoreCake();
    }
}

Побудова екземпляра TheSubбуде викликати обидва eatCake()іeatMoreCake()


1

Ви можете використовувати його для виклику методу суперкласу (наприклад, коли ви перевизначаєте такий метод, super.foo () тощо) - це дозволить вам зберегти цю функціональність і додати до неї все, що у вас є в заміненому метод.



1

Ви закликаєте super()спеціально запустити конструктор вашого суперкласу. Враховуючи, що клас може мати кілька конструкторів, ви можете або викликати певний конструктор, використовуючи, super()або одразу, super(param,param)ви можете дозволити Java обробляти це і викликати стандартний конструктор. Пам'ятайте, що класи, які дотримуються ієрархії класів, відповідають співвідношенню "є-а".


0

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


Неправда. Це відбудеться автоматично.
Марк Пітерс

Навіть якщо немає конструктора за замовчуванням? Звідки воно буде знати, що здати?
robev

Якщо конструктора за замовчуванням немає, вам потрібно зателефонувати super(some args), ні super(). Але справа в тому, що "повинен" є неправильним. Один із конструкторів суперкласу гарантовано буде викликаний, доки компіляція класу.
Марк Пітерс

Я не чітко дав зрозуміти, що коли я писав super (), я не мав на увазі конструктор без параметрів, я просто не хотів писати жодного. І так, я мав на увазі, що вам потрібно було зателефонувати йому, інакше він не скомпілюється, тому я сказав, що потрібно.
robev

1
Ще раз, вам НЕ потрібен явний виклик суперконструктора, якщо в батьківському класі існує конструктор no-arg. Завжди буде викликаний суперконструктор , тоді як ваше формулювання здається, що вам загрожує не викликати суперконструктор, якщо ви не введете super(...). Небезпеки цього абсолютно немає; просто небезпека, що він не скомпілюється.
Марк Пітерс

0

Я просто спробував, коментуючи супер (); робить те саме, не коментуючи це, як сказав @Mark Peters

package javaapplication6;

/**
 *
 * @author sborusu
 */
public class Super_Test {
    Super_Test(){
        System.out.println("This is super class, no object is created");
    }
}
class Super_sub extends Super_Test{
    Super_sub(){
       super();
       System.out.println("This is sub class, object is created");
    }
    public static void main(String args[]){
        new Super_sub();
    }
}

0

Зі сторінки документації oracle :

Якщо ваш метод замінює один із методів свого суперкласу, ви можете викликати перевизначений метод за допомогою ключового слова super.

Ви також можете використовувати superдля посилання на приховане поле (хоча приховування полів не рекомендується).

Використання superв конструкторі підкласів:

Виклик конструктора суперкласу повинен бути першим рядком у конструкторі підкласу.

Синтаксис для виклику конструктора суперкласу є

super();  

або:

super(parameter list);

З super(), викликається конструктор суперкласу no-argument. З super(parameter list), викликається конструктор суперкласу з відповідним списком параметрів.

Примітка: Якщо конструктор явно не викликає конструктор суперкласу, компілятор Java автоматично вставляє виклик до конструктора no-argument суперкласу . Якщо супер клас не має конструктора no-argument, ви отримаєте помилку під час компіляції.

Пов’язаний пост:

Поліморфізм проти перевизначення проти перевантаження

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.