super în Java

super apelează constructorul superclasei sau versiunea din superclasă a unei metode rescrise.

Sintaxă
super(argumente);     // constructorul superclasei (în constructor)
super.metoda();       // versiunea din superclasă a unei metode rescrise
super.camp            // câmpul din superclasă

Ce face super

În constructorul unei subclase, super(...) apelează constructorul superclasei, ca partea moștenită a obiectului să fie inițializată corect. Dacă nu îl scrii, compilatorul pune automat super() fără argumente, iar dacă superclasa nu are un astfel de constructor, apare o eroare de compilare.

Într-o metodă rescrisă, super.metoda() apelează versiunea din superclasă. Așa extinzi comportamentul în loc să îl înlocuiești complet: întâi faci ce făcea superclasa, apoi adaugi ce e nou.

super urcă un singur nivel: nu există super.super.metoda(). Ca și this, nu poate fi folosit în metode static.

Exemple

Exemplul 1: super(…) în constructor

Student trimite numele și vârsta constructorului din Persoana, apoi completează câmpul propriu.

class Persoana {
    final String nume;
    final int varsta;

    Persoana(String nume, int varsta) {
        this.nume = nume;
        this.varsta = varsta;
    }
}

class Student extends Persoana {
    final String universitate;

    Student(String nume, int varsta, String universitate) {
        super(nume, varsta);
        this.universitate = universitate;
    }
}

public class Main {
    public static void main(String[] args) {
        Student s = new Student("Mihai", 20, "Politehnica București");
        System.out.println(s.nume + ", " + s.varsta + " ani, " + s.universitate);
    }
}

Rezultat

Mihai, 20 ani, Politehnica București

Exemplul 2: super.metoda() pentru a extinde comportamentul

FacturaTVA.detalii() pornește de la textul produs de superclasă și adaugă TVA-ul. toString() din Factura refolosește la rândul ei detalii().

class Factura {
    final String client;
    final double suma;

    Factura(String client, double suma) {
        this.client = client;
        this.suma = suma;
    }

    String detalii() {
        return "client: " + client + ", sumă: " + suma + " lei";
    }

    @Override
    public String toString() {
        return "[" + detalii() + "]";
    }
}

class FacturaTVA extends Factura {
    FacturaTVA(String client, double suma) {
        super(client, suma);
    }

    @Override
    String detalii() {
        double tva = suma * 0.21;
        return super.detalii() + String.format(", TVA: %.2f, total: %.2f lei", tva, suma + tva);
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println(new Factura("SC Exemplu SRL", 1000));
        System.out.println(new FacturaTVA("SC Exemplu SRL", 1000));
    }
}

Rezultat

[client: SC Exemplu SRL, sumă: 1000.0 lei]
[client: SC Exemplu SRL, sumă: 1000.0 lei, TVA: 210.00, total: 1210.00 lei]

Greșeli frecvente

  • Pui super(...) după alte instrucțiuni care folosesc obiectul. Apelul trebuie să vină înaintea oricărei folosiri a lui this.
  • Uiți super. în metoda rescrisă și scrii detalii(): metoda se apelează pe ea însăși la nesfârșit și programul se termină cu StackOverflowError.
  • Încerci super.super.metoda(): nu compilează. Poți ajunge doar la superclasa directă.

Comenzi înrudite

  • Moștenire (extends): Cu extends o clasă moștenește câmpurile și metodele altei clase și le poate extinde sau rescrie; Java permite o singură superclasă.
  • this: this este referința către obiectul curent: deosebește câmpurile de parametri, apelează alt constructor sau returnează obiectul.
  • Constructori: Constructorul are numele clasei, nu are tip returnat și pregătește obiectul nou; o clasă poate avea mai mulți constructori.
  • Polimorfism: Polimorfismul înseamnă că același apel (f.arie()) execută metoda clasei reale a obiectului, chiar dacă variabila are tipul superclasei.