Kiedy używać super ()?


82

Obecnie uczę się dziedziczenia klas na moim kursie Java i nie rozumiem, kiedy używać super()wywołania?

Edycja:
znalazłem ten przykład kodu, w którym jest używany:super.variable

class A
{
    int k = 10;
}

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

Rozumiem więc, że tutaj musisz użyć, superaby uzyskać dostęp do kzmiennej w superklasie. Jednak w każdym innym przypadku, co robi super();? Na własną rękę?


31
Właściwie w tym przykładzie supernie jest wymagane odniesienie k. kmożna odwoływać się bezpośrednio. superbyłby wymagany tylko A.kwtedy, gdyby zadeklarowałeś inne pole o nazwie kw Test( Test.k).
— Mark Peters

Odpowiedzi:


143

Dzwonienie dokładnie super() jest zawsze zbędne. To jawnie robi to, co byłoby niejawnie zrobione w inny sposób. Dzieje się tak, ponieważ jeśli pominiesz wywołanie super-konstruktora, super-konstruktor bez argumentów zostanie i tak wywołany automatycznie. Nie mówiąc, że to zły styl; niektórzy lubią mówić wprost.

Jednak gdy staje się to przydatne, to superkonstruktor pobiera argumenty, które chcesz przekazać z podklasy.

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
Załóżmy, że metoda jest zastępowana w klasie podrzędnej, a następnie ponownie zastępowana w swojej klasie potomnej. (Dziedziczenie wielopoziomowe) A co, jeśli musimy wywołać metodę dziadka i rodzica jednocześnie w klasie wnuków. Jak będzie używany super?
— h8pathak

2
@ h8pathak: Jeśli pytasz, jak klasa potomna może ominąć implementację swojego rodzica, ale zadzwonić do dziadka, to nie jest to możliwe w Javie.
— Mark Peters

44

superjest stosowany do wywołania constructor, methodsa propertiesklasy nadrzędnej.


23

Możesz także użyć supersłowa kluczowego w podklasie, gdy chcesz wywołać metodę z klasy nadrzędnej, gdy zastąpiłeś ją w podklasie.

Przykład:

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

Tutaj linia super.print()wywołuje print()metodę nadklasy CellPhone. Wynik będzie:

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

1
czy to (String [] args) w głównej linii deklaracji metody? Wielkie dzięki!
— Appalachian Math


9

Można go użyć jako pierwszego wiersza konstruktora podklasy do wywołania konstruktora swojej klasy nadrzędnej.

Na przykład:

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

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

Skonstruowanie instancji TheSubwywoła zarówno eatCake()ieatMoreCake()


1

Możesz go użyć do wywołania metody nadklasy (np. Gdy nadpisujesz taką metodę, super.foo () itp.) - to pozwoliłoby ci zachować tę funkcjonalność i dodać do niej wszystko, co masz w nadpisaniu metoda.



1

Wzywasz super()specjalnie do uruchomienia konstruktora swojej nadklasy. Biorąc pod uwagę, że klasa może mieć wiele konstruktorów, możesz wywołać określony konstruktor za pomocą super()lub super(param,param)lub pozwolić Java obsłużyć to i wywołać standardowy konstruktor. Pamiętaj, że klasy, które są zgodne z hierarchią klas, są zgodne z relacją „jest-jest”.


0

Pierwsza linia konstruktora Twojej podklasy musi być wywołaniem, super()aby zapewnić wywołanie konstruktora nadklasy.


Nie prawda. Stanie się to automatycznie.
— Mark Peters

Nawet jeśli nie ma domyślnego konstruktora? Skąd będzie wiedział, co przejść?
— robev

Jeśli nie ma domyślnego konstruktora, musisz wywołać super(some args), nie super(). Ale chodzi o to, że „musi” jest błędne. Gwarantujemy, że jeden z konstruktorów superklasy będzie wywoływany, dopóki klasa się kompiluje.
— Mark Peters

Nie wyjaśniłem, że pisząc super () nie miałem na myśli konstruktora bez parametrów, po prostu nie miałem ochoty pisać. I tak, miałem na myśli, że musisz to wywołać lub nie będzie się kompilować, dlatego powiedziałem, że musisz.
— robev

1
Ponownie, NIE potrzebujesz jawnego wywołania super konstruktora, jeśli w klasie nadrzędnej istnieje konstruktor bezargumentowy. Zawsze zostanie wywołany superkonstruktor , podczas gdy twoje sformułowanie sprawia, że ​​brzmi to tak, jakbyś był w niebezpieczeństwie, że super konstruktor nie zostanie wezwany, jeśli tego nie zrobisz super(...). Nie ma absolutnie żadnego niebezpieczeństwa; po prostu niebezpieczeństwo, że się nie skompiluje.
— Mark Peters

0

Właśnie spróbowałem, komentując super (); robi to samo bez komentowania, jak powiedział @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

Ze strony dokumentacji oracle :

Jeśli twoja metoda przesłania jedną z metod jej nadrzędnej klasy, możesz wywołać przesłoniętą metodę za pomocą słowa kluczowego super.

Możesz również użyć superw odniesieniu do ukrytego pola (chociaż ukrywanie pól jest odradzane).

Użycie superw konstruktorze podklas:

Wywołanie konstruktora nadklasy musi być pierwszym wierszem konstruktora podklasy.

Składnia wywołania konstruktora nadklasy to

super();  

lub:

super(parameter list);

W super()przypadku wywoływany jest bezargumentowy konstruktor nadklasy. W super(parameter list)przypadku wywoływany jest konstruktor nadklasy z pasującą listą parametrów.

Uwaga: Jeśli konstruktor nie wywołuje jawnie konstruktora nadklasy, kompilator języka Java automatycznie wstawia wywołanie do konstruktora bezargumentowego nadklasy . Jeśli super klasa nie ma konstruktora bezargumentowego, wystąpi błąd kompilacji.

Powiązany post:

Polimorfizm a zastępowanie a przeciążanie

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.