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ę?

muttley91
źródło
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");
    }
}
Mark Peters
źródło
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.

Zain Shaikh
źródło
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
Dhiraj Shekar
źródło
1
czy to (String [] args) w głównej linii deklaracji metody? Wielkie dzięki!
Appalachian Math
9

Kiedy chcesz wywołać konstruktor superklasy - aby zainicjować pola w nim zawarte. Zapoznaj się z tym artykułem, aby dowiedzieć się, kiedy go używać:

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

Jon
źródło
4
Jak jest napisane w odsyłaczu, nigdy nie musisz dzwonić super(), ponieważ Java domyślnie go doda. Ale musisz zadzwonić, super(args)jeśli potrzebujesz innego niż domyślny konstruktora nadrzędnego.
Michael Brewer-Davis
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()

TartanLlama
źródło
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.

AHungerArtist
źródło
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”.

0xCAFEBABE
źródło
0

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

robev
źródło
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();
    }
}
Shiva Borusu
źródło
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

Ravindra babu
źródło