translated markdown.## 1. Relazione tra ereditarietà e super
Per comprendere la parola chiave super di Java, dovresti prima capire l’ereditarietà.
super non è qualcosa che si memorizza isolatamente—il suo significato diventa chiaro una volta che vedi come una classe figlia e una classe genitore lavorano insieme.
In questa sezione imparerai cos’è l’ereditarietà e perché super esiste, usando spiegazioni per principianti ed esempi di codice semplici.
- 1 2. Come usare super (3 pattern fondamentali)
- 1.1 2.1 Chiamare un costruttore del genitore (super() / super(args…))
- 1.1.1 2.1.1 Rapido ripasso: cos’è un costruttore?
- 1.1.2 2.1.2 Nell’ereditarietà, il costruttore del genitore viene eseguito per primo
- 1.1.3 2.1.3 super() viene inserito automaticamente (quando possibile)
- 1.1.4 2.1.4 Quando il genitore ha solo un costruttore parametrizzato
- 1.1.5 2.1.5 super(...) deve essere la prima riga nel costruttore
- 1.2 2.2 Chiamare un Metodo del Genitore (super.method())
- 1.3 2.3 Accedere a un Campo del Genitore (super.field)
- 1.4 2.4 Riepilogo dei 3 pattern
- 1.1 2.1 Chiamare un costruttore del genitore (super() / super(args…))
- 2 3. Esempi Pratici per Padroneggiare super
- 2.1 3.1 Esempio 1: Ordine di chiamata del costruttore (Genitore → Figlio)
- 2.2 3.2 Esempio 2: Il genitore ha solo un costruttore parametrizzato
- 2.3 3.3 Example 3: Calling a parent method after overriding (super.method())
- 2.4 3.4 Example 4: Accessing a hidden parent field (super.field)
- 2.5 3.5 Example 5: Calling both parent and child versions clearly
- 2.6 3.6 A realistic example: shared logic in the parent class
- 2.7 3.7 Section summary
- 3 4. Difference Between this and super
- 3.1 4.1 this si riferisce all’oggetto corrente (l’istanza figlia)
- 3.2 4.2 super si riferisce al lato della classe genitore
- 3.3 4.3 Il modo più semplice per ricordare la differenza
- 3.4 4.4 Uso di this e super con i campi
- 3.5 4.5 Uso di this e super con i metodi
- 3.6 4.6 Costruttori: this() vs super()
- 3.7 4.7 Non è possibile usare this() e super() insieme
- 3.8 4.8 Promemoria importante: super non crea un nuovo oggetto
- 3.9 4.9 Riepilogo della sezione
- 4 5. Errori comuni e insidie (come evitare gli errori)
- 4.1 5.1 Scrivere super(...) nel posto sbagliato (regola del costruttore)
- 4.2 5.2 Dimenticare super(args...) quando il genitore non ha un costruttore senza argomenti
- 4.3 5.3 Tentare di usare sia this() sia super() nello stesso costruttore
- 4.4 5.4 Tentare di usare super all’interno di un metodo statico
- 4.5 5.5 Confondere super con “creare un oggetto genitore”
- 4.6 5.6 Usare super.field troppo spesso (nascondere i campi è generalmente una cattiva idea)
- 4.7 5.7 “Se chiamo super.method(), viene eseguita solo la logica del genitore” (non sempre)
- 4.8 5.8 Checklist veloce (per evitare errori da principianti)
- 5 6. Conclusione (Punti Chiave)
- 5.1 6.1 Cosa significa super in Java?
- 5.2 6.2 I 3 modi più importanti per usare super
- 5.3 6.3 this vs super (il modo più semplice per capirlo)
- 5.4 6.4 La maggior parte degli errori avviene intorno ai costruttori
- 5.5 6.5 Conclusione finale: super ti aiuta a riutilizzare ed estendere in modo sicuro la logica del genitore
- 6 7. FAQ (Domande Frequenti)
- 6.1 7.1 Quando dovrei usare super in Java?
- 6.2 7.2 Cosa succede se non scrivo super()?
- 6.3 7.3 Qual è la differenza tra super() e this()?
- 6.4 7.4 Posso usare sia this() che super() nello stesso costruttore?
- 6.5 7.5 Posso usare super all’interno di un metodo statico?
- 6.6 7.6 super crea un nuovo oggetto genitore?
- 6.7 7.7 Se chiamo super.method(), esegue sempre solo la logica del genitore?
- 6.8 7.8 Dovrei usare super.field spesso?
- 6.9 7.9 super può essere usato con le interfacce?
- 6.10 7.10 Qual è il modo più veloce per padroneggiare super?
1.1 Cos’è l’ereditarietà in Java? (Nozioni di base di extends)
In Java, l’ereditarietà ti permette di creare una nuova classe basata su una classe esistente.
- Classe genitore (superclasse) : la classe base
- Classe figlia (sottoclasse) : la classe che eredita dalla classe genitore
Quando una classe figlia estende una classe genitore, può riutilizzare i campi e i metodi del genitore senza riscriverli.
Sintassi di base dell’ereditarietà (extends)
class Parent {
void hello() {
System.out.println("Hello from Parent");
}
}
class Child extends Parent {
}
Qui, Child eredita il metodo hello() da Parent.
public class Main {
public static void main(String[] args) {
Child child = new Child();
child.hello(); // calling a method inherited from Parent
}
}
Output:
Hello from Parent
Quindi, anche se Child non definisce hello(), può comunque chiamarlo perché l’ha ereditato.
1.2 Perché abbiamo bisogno di super?
A questo punto, potresti pensare:
“Se la classe figlia eredita già tutto dal genitore, perché dovremmo aver bisogno di
super?”
In molti casi, non è necessario scrivere super esplicitamente.
Tuttavia, super diventa necessario quando vuoi accedere chiaramente alla versione del genitore di qualcosa.
Le situazioni comuni includono:
- La classe figlia sovrascrive un metodo, ma vuoi comunque chiamare la versione del genitore
- La classe figlia e la classe genitore hanno campi con lo stesso nome
- È necessario chiamare un costruttore specifico del genitore usando argomenti
In breve:
superè usato quando vuoi riferirti esplicitamente al lato della classe genitore.
1.3 Sovrascrittura e super (Mantenere il comportamento del genitore)
Uno dei motivi più comuni per usare super è la sovrascrittura di metodi.
La sovrascrittura significa che la classe figlia fornisce la propria versione di un metodo che esiste già nella classe genitore.
Esempio: sovrascrivere un metodo
class Parent {
void greet() {
System.out.println("Parent: Hello!");
}
}
class Child extends Parent {
@Override
void greet() {
System.out.println("Child: Hi!");
}
}
Ora, se chiami greet() su un oggetto Child:
public class Main {
public static void main(String[] args) {
Child child = new Child();
child.greet();
}
}
Output:
Child: Hi!
Viene eseguita la versione della figlia, perché la sovrascrittura dà priorità alla classe figlia.
Chiamare la versione del genitore con super.greet()
A volte non vuoi sostituire completamente il comportamento del genitore—vuoi solo aggiungere logica extra.
È qui che super.method() è utile:
class Parent {
void greet() {
System.out.println("Parent: Hello!");
}
}
class Child extends Parent {
@Override
void greet() {
super.greet(); // call parent version
System.out.println("Child: Hi!");
}
}
Output:
Parent: Hello!
Child: Hi!
Questo è un modello molto pratico:
- La classe genitore gestisce il comportamento comune
- La classe figlia aggiunge comportamento personalizzato
1.4 Quando genitore e figlia hanno lo stesso nome di campo
Un’altra situazione in cui super è importante è quando una classe genitore e una classe figlia hanno campi con lo stesso nome.
Esempio:
class Parent {
int value = 100;
}
class Child extends Parent {
int value = 200;
void printValue() {
System.out.println(value);
}
}
Qui, value si riferisce al campo della classe figlia, quindi l’output sarà:
200
.Se vuoi accedere al campo della classe genitore, usa super.value:
class Child extends Parent {
int value = 200;
void printValue() {
System.out.println(value); // child value
System.out.println(super.value); // parent value
}
}
Output:
200
100
Punto chiave:
value→ campo della classe figliasuper.value→ campo della classe genitore
1.5 Cosa significa davvero super (Definizione semplice)
Ora puoi riassumere super così:
superè una parola chiave che ti permette di accedere esplicitamente alla versione della classe genitore di campi, metodi e costruttori.
Se devi ricordare una sola frase, ricordala così:
supersignifica “usa la versione della classe genitore”.
Nella sezione successiva imparerai i 3 modi più importanti di usare super, con esempi chiari per ciascuno.
2. Come usare super (3 pattern fondamentali)
Ora che hai capito cosa significa super, concentriamoci su come viene effettivamente usato in Java.
Nel codice reale, super appare in tre pattern principali:
- Chiamare un costruttore del genitore (
super()/super(args…)) - Chiamare un metodo del genitore (
super.method()) - Accedere a un campo del genitore (
super.field)
Una volta appresi questi tre, super diventa molto facile da riconoscere e usare correttamente.
2.1 Chiamare un costruttore del genitore (super() / super(args…))
2.1.1 Rapido ripasso: cos’è un costruttore?
Un costruttore è un metodo speciale che viene eseguito quando crei un oggetto.
class Person {
Person() {
System.out.println("Person constructor");
}
}
I costruttori servono per l’inizializzazione, ad esempio per impostare i campi.
2.1.2 Nell’ereditarietà, il costruttore del genitore viene eseguito per primo
Nell’ereditarietà Java, la creazione di un oggetto figlio inizia sempre inizializzando prima la parte del genitore.
Ciò significa:
Costruttore del genitore → Costruttore della figlia
Esempio:
class Parent {
Parent() {
System.out.println("Parent constructor");
}
}
class Child extends Parent {
Child() {
System.out.println("Child constructor");
}
}
public class Main {
public static void main(String[] args) {
new Child();
}
}
Output:
Parent constructor
Child constructor
Anche se non abbiamo scritto super(), il costruttore del genitore è stato comunque eseguito.
2.1.3 super() viene inserito automaticamente (quando possibile)
Se la classe genitore ha un costruttore senza argomenti, Java inserisce automaticamente questa riga all’inizio del costruttore della figlia:
super();
Quindi questi due costruttori sono effettivamente equivalenti:
Child() {
System.out.println("Child constructor");
}
Child() {
super(); // implicitly inserted by the compiler
System.out.println("Child constructor");
}
2.1.4 Quando il genitore ha solo un costruttore parametrizzato
Questo è uno degli errori più comuni per i principianti.
Se la classe genitore non ha un costruttore senza argomenti, Java non può inserire super() automaticamente.
Esempio (causerà un errore di compilazione):
class Parent {
Parent(int x) {
System.out.println("Parent: " + x);
}
}
class Child extends Parent {
Child() {
System.out.println("Child created");
}
}
Perché fallisce:
- Il compilatore tenta di inserire
super(); - Ma
Parent()non esiste
✅ Correzione: chiamare esplicitamente il costruttore corretto del genitore
class Child extends Parent {
Child() {
super(10);
System.out.println("Child created");
}
}
Output:
Parent: 10
Child created
2.1.5 super(...) deve essere la prima riga nel costruttore
Java richiede che super(...) sia la prima istruzione in un costruttore.
❌ Errato:
Child() {
System.out.println("Something first");
super(10); // compile error
}
✅ Corretto:
Child() {
super(10);
System.out.println("Child logic");
}
Motivo:
- Il genitore deve essere inizializzato prima che il figlio possa eseguire in sicurezza la propria logica.
2.2 Chiamare un Metodo del Genitore (super.method())
Un altro caso d’uso molto comune è chiamare il metodo del genitore dopo averlo sovrascritto.
2.2.1 Esempio base
class Parent {
void show() {
System.out.println("Parent show()");
}
}
class Child extends Parent {
@Override
void show() {
System.out.println("Child show()");
}
void test() {
super.show(); // parent version
show(); // child version
}
}
public class Main {
public static void main(String[] args) {
new Child().test();
}
}
Output:
Parent show()
Child show()
2.2.2 Quando è utile?
super.method() è utile quando:
- Il metodo del genitore contiene logica comune
- Il metodo del figlio deve estendere il comportamento invece di sostituirlo
- Vuoi evitare di copiare‑incollare la logica del genitore nel figlio
Esempio:
class Parent {
void process() {
System.out.println("Common processing");
}
}
class Child extends Parent {
@Override
void process() {
super.process();
System.out.println("Child-specific processing");
}
}
Questo schema mantiene il tuo codice pulito e manutenibile.
2.3 Accedere a un Campo del Genitore (super.field)
I campi funzionano in modo simile. Se sia il genitore che il figlio hanno un campo con lo stesso nome, il campo del figlio nasconde quello del genitore.
Esempio:
class Parent {
int value = 100;
}
class Child extends Parent {
int value = 200;
void print() {
System.out.println(value); // child field
System.out.println(super.value); // parent field
}
}
public class Main {
public static void main(String[] args) {
new Child().print();
}
}
Output:
200
100
2.3.1 Dovresti farlo in progetti reali?
Di solito, avere lo stesso nome di campo in genitore e figlio non è una buona idea perché può confondere i lettori.
Tuttavia, può succedere quando:
- Stai mantenendo codice legacy
- Sei costretto a rispettare un design di classe genitore esistente
- Devi differenziare chiaramente i valori genitore vs figlio
In quei casi, super.field è lo strumento corretto.
2.4 Riepilogo dei 3 pattern
Puoi ricordare super così:
super()/super(args…)→ chiama il costruttore del genitoresuper.method()→ chiama il metodo del genitoresuper.field→ accede al campo del genitore
Nella sezione successiva approfondiremo con esempi di codice pratici così potrai vedere chiaramente come questi pattern si comportano durante l’esecuzione.
3. Esempi Pratici per Padroneggiare super
A questo punto, conosci già i tre modi fondamentali per usare super.
Ora facciamo in modo che questa conoscenza rimanga passando in rassegna esempi pratici.
Questa sezione si concentra su:
- Ordine di esecuzione
- Cosa viene chiamato e perché
- Come
supermodifica il comportamento nel codice reale
3.1 Esempio 1: Ordine di chiamata del costruttore (Genitore → Figlio)
La regola più importante da ricordare:
Quando si crea un oggetto figlio, Java inizializza sempre prima la parte del genitore.
class Parent {
Parent() {
System.out.println("Parent constructor");
}
}
class Child extends Parent {
Child() {
super(); // optional here, but allowed
System.out.println("Child constructor");
}
}
public class Main {
public static void main(String[] args) {
new Child();
}
}
Output:
Parent constructor
Child constructor
Punto chiave:
Anche se rimuovi super(), il risultato è lo stesso (purché il genitore abbia un costruttore senza argomenti).
3.2 Esempio 2: Il genitore ha solo un costruttore parametrizzato
Se la classe genitore non ha un costruttore senza argomenti, il figlio deve chiamare esplicitamente quello corretto.
class Parent {
Parent(String name) {
System.out.println("Parent: " + name);
}
}
.class Child extends Parent {
Child() {
super("Taro");
System.out.println("Child created");
}
}
public class Main {
public static void main(String[] args) {
new Child();
}
}
Output:
Parent: Taro
Child created
Key point:
If you forget super("Taro"), Java tries to insert super() automatically and fails.
3.3 Example 3: Calling a parent method after overriding (super.method())
This is one of the most useful patterns in real projects.
class Parent {
void greet() {
System.out.println("Hello from Parent");
}
}
class Child extends Parent {
@Override
void greet() {
super.greet(); // call parent behavior
System.out.println("Hello from Child");
}
}
public class Main {
public static void main(String[] args) {
new Child().greet();
}
}
Output:
Hello from Parent
Hello from Child
Key point:
You can extend parent behavior without rewriting it.
3.4 Example 4: Accessing a hidden parent field (super.field)
If parent and child both define a field with the same name, the child version hides the parent version.
class Parent {
int value = 100;
}
class Child extends Parent {
int value = 200;
void printValues() {
System.out.println("Child value: " + value);
System.out.println("Parent value: " + super.value);
}
}
public class Main {
public static void main(String[] args) {
new Child().printValues();
}
}
Output:
Child value: 200
Parent value: 100
Key point:
valuerefers to the child’s fieldsuper.valuerefers to the parent’s field
3.5 Example 5: Calling both parent and child versions clearly
This is a great example to remove confusion.
class Parent {
void show() {
System.out.println("Parent show()");
}
}
class Child extends Parent {
@Override
void show() {
System.out.println("Child show()");
}
void test() {
super.show(); // parent version
this.show(); // child version (same as just calling show())
}
}
public class Main {
public static void main(String[] args) {
new Child().test();
}
}
Output:
Parent show()
Child show()
Key point:
super.show()= parentthis.show()= child
3.6 A realistic example: shared logic in the parent class
In real applications, parent classes often contain common logic such as logging, validation, or setup steps.
class BaseService {
void execute() {
System.out.println("[LOG] Start execution");
}
}
class UserService extends BaseService {
@Override
void execute() {
super.execute(); // reuse shared behavior
System.out.println("UserService logic running...");
}
}
public class Main {
public static void main(String[] args) {
new UserService().execute();
}
}
Output:
[LOG] Start execution
UserService logic running...
Why this is useful:
- You avoid duplicating common behavior
- The child focuses only on what’s unique
- Your code becomes easier to maintain
3.7 Section summary
From these examples, you should remember:
- Parent constructors run before child constructors
super(args...)is required if the parent has no no-arg constructorsuper.method()is perfect for reusing and extending behaviorsuper.fieldhelps when parent and child fields share the same name
Next, we’ll clarify one of the most confusing topics for beginners:
What’s the difference between
thisandsuper?
4. Difference Between this and super
When learning Java’s super, you will almost always see this at the same time.
Both are reference keywords, so it’s easy for beginners to mix them up.
In this section, you’ll learn:
- Cosa significa
this - Cosa significa
super - Come usarli correttamente con campi, metodi e costruttori
4.1 this si riferisce all’oggetto corrente (l’istanza figlia)
this significa:
“l’istanza corrente dell’oggetto”
È più comunemente usato quando il nome di un campo e il nome di un parametro del costruttore sono gli stessi.
class User {
String name;
User(String name) {
this.name = name; // field = parameter
}
}
Qui:
name(lato destro) è il parametro del costruttorethis.name(lato sinistro) è il campo dell’istanza
Quindi this ti aiuta a evitare confusioni. 
4.2 super si riferisce al lato della classe genitore
super si riferisce alla parte della classe genitore (superclasse) dell’oggetto corrente.
Significa:
“usa la versione della classe genitore”
Lo usi principalmente quando vuoi accedere ai membri della classe genitore che sono nascosti o sovrascritti.
4.3 Il modo più semplice per ricordare la differenza
Un modo adatto ai principianti per memorizzare:
this→ il lato della classe figliasuper→ il lato della classe genitore
Non sono due oggetti diversi.
Sono due “viste” diverse dello stesso oggetto.
4.4 Uso di this e super con i campi
Se sia il genitore che il figlio definiscono un campo con lo stesso nome, puoi scegliere chiaramente quale vuoi.
class Parent {
int value = 100;
}
class Child extends Parent {
int value = 200;
void print() {
System.out.println(this.value); // child field
System.out.println(super.value); // parent field
}
}
public class Main {
public static void main(String[] args) {
new Child().print();
}
}
Output:
200
100
Punto chiave:
this.value= campo del figliosuper.value= campo del genitore
Inoltre, in Java, this è spesso opzionale:
System.out.println(value);
è lo stesso di:
System.out.println(this.value);
4.5 Uso di this e super con i metodi
I metodi sono l’area più comune in cui la differenza tra this e super è importante—soprattutto con l’override.
class Parent {
void show() {
System.out.println("Parent show()");
}
}
class Child extends Parent {
@Override
void show() {
System.out.println("Child show()");
}
void test() {
this.show(); // child method (same as show())
super.show(); // parent method
}
}
public class Main {
public static void main(String[] args) {
new Child().test();
}
}
Output:
Child show()
Parent show()
Punto chiave:
this.show()→ versione del figliosuper.show()→ versione del genitore
4.6 Costruttori: this() vs super()
Questa è una delle parti più confuse per i principianti, ma è molto importante.
this()chiama un altro costruttore nella stessa classesuper()chiama un costruttore nella classe genitore
4.6.1 Esempio di this() (chaining di costruttori nella stessa classe)
class User {
String name;
int age;
User() {
this("NoName", 0); // call another constructor
}
User(String name, int age) {
this.name = name;
this.age = age;
}
}
Questo è utile perché evita di ripetere la logica di inizializzazione.
4.6.2 Esempio di super() (chiamata al costruttore del genitore)
class Parent {
Parent() {
System.out.println("Parent constructor");
}
}
class Child extends Parent {
Child() {
super(); // initialize parent
System.out.println("Child constructor");
}
}
Output:
Parent constructor
Child constructor
4.7 Non è possibile usare this() e super() insieme
Molti principianti provano qualcosa del genere:
Child() {
this(1);
super(); // error
}
Questo non è consentito.
Motivo:
- Sia
this()chesuper()devono essere la prima riga nel costruttore - Solo uno dei due può essere il primo
Quindi devi sceglierne uno.
4.8 Promemoria importante: super non crea un nuovo oggetto
super non crea un oggetto genitore separato.
Invece:
this= oggetto corrente visualizzato come figliosuper= stesso oggetto visualizzato come genitore
Ecco perché super è meglio considerarlo una parola‑chiave di riferimento, non un creatore di oggetti.
4.9 Riepilogo della sezione
thissi riferisce all’oggetto corrente (lato figlio)supersi riferisce al lato della classe genitorethis()chiama un altro costruttore nella stessa classesuper()chiama un costruttore nella classe genitorethis()esuper()non possono essere usati insieme
Successivamente, tratteremo gli errori comuni e i pattern di errore in modo che tu possa evitare le trappole più frequenti per i principianti.
5. Errori comuni e insidie (come evitare gli errori)
La parola‑chiave super di Java è potente, ma è anche facile da usare in modo errato—soprattutto quando stai ancora imparando l’ereditarietà e i costruttori.
In questa sezione imparerai gli errori più comuni che commettono i principianti e come correggerli rapidamente.
5.1 Scrivere super(...) nel posto sbagliato (regola del costruttore)
Una delle regole più importanti:
super(...)deve essere la prima istruzione all’interno di un costruttore.
❌ Sbagliato (errore di compilazione):
class Parent {
Parent(int x) {}
}
class Child extends Parent {
Child() {
System.out.println("Do something first");
super(10); // ERROR: must be first line
}
}
✅ Corretto:
class Child extends Parent {
Child() {
super(10);
System.out.println("Child logic");
}
}
Perché?
Perché la parte genitore dell’oggetto deve essere inizializzata prima che venga eseguita la logica del figlio.
5.2 Dimenticare super(args...) quando il genitore non ha un costruttore senza argomenti
Se la classe genitore ha solo un costruttore parametrizzato, Java non può inserire automaticamente super().
❌ Sbagliato:
class Parent {
Parent(String name) {}
}
class Child extends Parent {
Child() {
// compiler tries to insert super() here -> ERROR
}
}
✅ Corretto:
class Child extends Parent {
Child() {
super("Taro");
}
}
Questo è un errore di compilazione molto comune per i principianti, quindi controlla sempre i costruttori del genitore.
5.3 Tentare di usare sia this() sia super() nello stesso costruttore
I principianti spesso pensano:
“Voglio chiamare un altro costruttore E il costruttore del genitore.”
Ma Java non lo consente.
❌ Sbagliato:
class Parent {
Parent() {}
}
class Child extends Parent {
Child() {
this(1);
super(); // ERROR
}
Child(int x) {}
}
Motivo:
this()esuper()devono entrambi essere la prima riga- Solo uno dei due può essere per primo
Quindi devi progettare i tuoi costruttori in modo che ne venga usato solo uno direttamente.
5.4 Tentare di usare super all’interno di un metodo statico
super è legato all’istanza corrente dell’oggetto, quindi non funziona nei metodi statici.
❌ Sbagliato (concettualmente):
class Parent {
void hello() {}
}
class Child extends Parent {
static void test() {
super.hello(); // ERROR
}
}
Punto chiave:
- I metodi statici appartengono alla classe, non a un’istanza
supersi riferisce alla parte genitore di un’istanza
Perciò Java impedisce questa operazione.
5.5 Confondere super con “creare un oggetto genitore”
Alcuni principianti presumono:
“Usare
supercrea un oggetto genitore separato.”
Non è vero.
super non crea un nuovo oggetto.
Accede semplicemente al lato della classe genitore dello stesso oggetto.
Pensalo così:
this= stesso oggetto, vista figliosuper= stesso oggetto, vista genitore
5.6 Usare super.field troppo spesso (nascondere i campi è generalmente una cattiva idea)
Sì, super.field esiste—ma nella maggior parte dei progetti reali dovresti evitare di creare campi genitore/figlio con lo stesso nome.
Esempio (design confuso):
class Parent {
int value = 100;
}
class Child extends Parent {
int value = 200; // hides parent field
}
Anche se super.value funziona, questo design rende il codice più difficile da leggere e mantenere.
Pratica migliore:
- Usa nomi di campo diversi
- Mantieni i campi privati ed esponili tramite metodi (getter)
- Evita di nascondere i campi a meno che non sia assolutamente necessario
5.7 “Se chiamo super.method(), viene eseguita solo la logica del genitore” (non sempre)
Questo è leggermente più avanzato, ma utile da sapere.
Quando chiami super.method(), chiami sicuramente il metodo del genitore.
Tuttavia, all’interno di quel metodo del genitore, se chiama un altro metodo che il figlio sovrascrive, potrebbe essere eseguita la versione del figlio.
Esempio:
class Parent {
void a() {
b(); // calls b()
}
void b() {
System.out.println("Parent b()");
}
}
class Child extends Parent {
@Override
void b() {
System.out.println("Child b()");
}
}
public class Main {
public static void main(String[] args) {
Child c = new Child();
c.a();
}
}
Output:
Child b()
Anche se a() è nel genitore, chiama b(), e b() è sovrascritto nel figlio.
Conclusione per i principianti:
super.method() chiama la versione del genitore di quel metodo, ma le chiamate a metodi all’interno di esso possono comunque seguire le regole di overriding.
5.8 Checklist veloce (per evitare errori da principianti)
Prima di usare super, verifica questi punti:
- Il
super(...)è la prima riga nel costruttore? - La classe genitore ha un costruttore senza argomenti?
- Stai cercando di usare sia
this()chesuper()? - Stai usando
superall’interno di un metodo statico? - Stai nascondendo campi con lo stesso nome inutilmente?
6. Conclusione (Punti Chiave)
In questo articolo, hai imparato cos’è la parola chiave super di Java, perché esiste e come usarla correttamente nel codice reale.
Ricapitoliamo tutto con i punti più importanti da ricordare.
6.1 Cosa significa super in Java?
super è una parola chiave che ti permette di accedere esplicitamente alla parte della classe genitore (superclasse) di un oggetto.
Viene principalmente usato nell’ereditarietà (extends) quando vuoi fare riferimento alla versione genitore di:
- costruttori
- metodi
- campi
In termini semplici:
supersignifica “usa la versione della classe genitore.”
6.2 I 3 modi più importanti per usare super
Puoi memorizzare super in questi tre schemi:
1) Chiamare il costruttore del genitore
super()super(args...)
Questo è usato quando è necessario inizializzare correttamente la classe genitore, specialmente se il genitore richiede argomenti.
2) Chiamare il metodo del genitore
super.method()
Questo è utile quando sovrascrivi un metodo ma vuoi comunque riutilizzare il comportamento del genitore.
3) Accedere al campo del genitore
super.field
Questo è usato quando sia il genitore che il figlio hanno un campo con lo stesso nome e vuoi riferirti chiaramente a quello del genitore.
6.3 this vs super (il modo più semplice per capirlo)
Molti principianti confondono queste due parole chiave, ma la differenza è semplice:
this→ l’oggetto corrente (visuale lato figlio)super→ la visuale lato genitore dello stesso oggetto
Non rappresentano due oggetti diversi.
6.4 La maggior parte degli errori avviene intorno ai costruttori
Se vuoi evitare gli errori più comuni, ricorda queste regole:
super(...)deve essere la prima riga all’interno di un costruttore- Se il genitore non ha un costruttore senza argomenti, devi scrivere
super(args...) - Non puoi usare
this()esuper()insieme nello stesso costruttore supernon funziona nei metodi statici
6.5 Conclusione finale: super ti aiuta a riutilizzare ed estendere in modo sicuro la logica del genitore
Il vero potere di super è che ti permette di:
- mantenere la logica condivisa nella classe genitore
- estendere il comportamento nella classe figlio
- evitare di copiare‑incollare codice
- rendere l’ereditarietà più pulita e più facile da mantenere
Se ricordi una sola frase da questo intero articolo, ricordala:
superè la parola chiave da usare quando vuoi la versione della classe genitore.
7. FAQ (Domande Frequenti)
Ecco le domande più comuni che i principianti pongono quando imparano la parola chiave super di Java.
Se ti senti ancora insicuro su alcune parti, questa sezione dovrebbe chiarire le cose rapidamente.
7.1 Quando dovrei usare super in Java?
Usi tipicamente super in queste situazioni:
- Quando vuoi chiamare un costruttore del genitore (
super()/super(args...)) - Quando sovrascrivi un metodo ma vuoi ancora chiamare il metodo del genitore (
super.method()) - Quando il genitore e il figlio hanno lo stesso nome di campo e vuoi il campo del genitore (
super.field)
Per i principianti, il caso più comune e utile è:
sovrascrivere un metodo e chiamare la logica del genitore usando
super.method().
7.2 Cosa succede se non scrivo super()?
Se la classe genitore ha un costruttore senza argomenti, Java inserisce automaticamente:
super();
all’inizio del costruttore del figlio.
Quindi in molti casi, non è necessario scriverlo manualmente.
Tuttavia, se la classe genitore non ha un costruttore senza argomenti, il codice fallirà a meno che tu non chiami esplicitamente quello corretto con argomenti.
7.3 Qual è la differenza tra super() e this()?
Chiamano costruttori diversi:
super()→ chiama un costruttore nella classe genitorethis()→ chiama un costruttore nella stessa classe
Idea di esempio:
- Usa
this()per ridurre il codice duplicato nei costruttori - Usa
super()per inizializzare correttamente la parte genitore dell’oggetto
7.4 Posso usare sia this() che super() nello stesso costruttore?
No, non puoi.
Motivo:
- Sia
this()chesuper()devono essere la prima istruzione nel costruttore - Solo un’istruzione può essere la prima
Quindi Java ti costringe a sceglierne una.
7.5 Posso usare super all’interno di un metodo statico?
No (in generale).
super è relativo all’istanza dell’oggetto corrente, ma i metodi statici appartengono alla classe stessa e non hanno un riferimento a un’istanza.
È per questo che l’uso di super nei metodi statici risulta in un errore di compilazione.
7.6 super crea un nuovo oggetto genitore?
No.
super non crea alcun nuovo oggetto.
Accede semplicemente alla vista della classe genitore dello stesso oggetto.
Un modo utile per pensarlo:
this= stesso oggetto visto come figliosuper= stesso oggetto visto come genitore
7.7 Se chiamo super.method(), esegue sempre solo la logica del genitore?
super.method() chiama sempre la versione del genitore di quel metodo.
Tuttavia, se il metodo del genitore chiama internamente un altro metodo che il figlio sovrascrive, allora la versione del figlio potrebbe essere eseguita a causa delle regole di overriding di Java.
Lezione per principianti:
super.method()chiama la versione del genitore, ma le chiamate di metodo al suo interno potrebbero ancora essere influenzate dall’overriding.
7.8 Dovrei usare super.field spesso?
Di solito, no.
Se hai frequentemente bisogno di super.field, potrebbe significare che il tuo design è confuso perché il genitore e il figlio condividono lo stesso nome di campo.
Nei progetti reali, è meglio evitare la nascondimento dei campi a meno che tu non abbia un motivo forte (come codice legacy o vincoli esterni).
7.9 super può essere usato con le interfacce?
Nell’ereditarietà normale (extends), super si riferisce alla classe genitore.
Tuttavia, Java permette anche una sintassi speciale per chiamare un metodo predefinito di un’interfaccia:
InterfaceName.super.method();
Questo è più avanzato, quindi se sei un principiante, concentrati prima su:
- ereditarietà di classe
super()/super.method()/super.field
7.10 Qual è il modo più veloce per padroneggiare super?
Un percorso di apprendimento semplice:
- Scrivi una classe genitore/figlio di base e conferma l’ordine dei costruttori
- Sovrascrivi un metodo e chiama
super.method() - Confronta
thisvssupercon campi e metodi - Esercitati a correggere errori relativi ai costruttori
La migliore pratica è scrivere piccoli esempi ed eseguirli.

