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.