Differenza tra “questo” e “super” parole chiave in Java

Qual è la differenza tra le parole chiave this e super ?

Entrambi sono utilizzati per accedere ai costruttori di class, giusto? Qualcuno di voi può spiegare?

Consideriamo questa situazione

 class Animal { void eat() { System.out.println("animal : eat"); } } class Dog extends Animal { void eat() { System.out.println("dog : eat"); } void anotherEat() { super.eat(); } } public class Test { public static void main(String[] args) { Animal a = new Animal(); a.eat(); Dog d = new Dog(); d.eat(); d.anotherEat(); } } 

L’output sarà

 animal : eat dog : eat animal : eat 

La terza riga sta stampando “animal: eat” perché stiamo chiamando super.eat() . Se chiamassimo this.eat() , sarebbe stato stampato come “cane: mangia”.

super è usato per accedere ai metodi della class base mentre this è usato per accedere ai metodi della class corrente.

Estendendo la nozione, se scrivi super() , si riferisce al costruttore della class base, e se scrivi this() , si riferisce al costruttore della stessa class in cui stai scrivendo questo codice.

this è un riferimento all’object digitato come class corrente e super è un riferimento all’object digitato come class genitore.

Nel costruttore, this() chiama un costruttore definito nella class corrente. super() chiama un costruttore definito nella class genitore. Il costruttore può essere definito in qualsiasi class genitore, ma farà riferimento a quello sottoposto a override più vicino alla class corrente. Le chiamate ad altri costruttori in questo modo possono essere eseguite solo come prima riga in un costruttore.

I metodi di chiamata funzionano allo stesso modo. La chiamata this.method() chiama un metodo definito nella class corrente dove super.method() chiamerà lo stesso metodo definito nella class genitore.

Dalla tua domanda, deduco che tu stia davvero chiedendo l’uso di this e del super nel concatenamento del costruttore; per esempio

 public class A extends B { public A(...) { this(...); ... } } 

contro

 public class A extends B { public A(...) { super(...); ... } } 

La differenza è semplice:

  • this modulo si lega a un costruttore nella class corrente; cioè nella class A

  • La super forma si lega a un costruttore nella superclass immediata; cioè nella class B

this riferisce ad un riferimento della class corrente .
super riferisce al genitore della class corrente (che ha chiamato la parola chiave super ).

In this , consente di accedere a metodi / attributi della class corrente (inclusi i propri metodi / attributi privati).

super ti consente di accedere a metodi / attributi pubblici / protetti della class genitore (base). Non puoi vedere il metodo / gli attributi privati ​​del genitore.

this è usato per accedere ai metodi e ai campi dell’object corrente. Per questo motivo, ad esempio, non ha alcun significato nei metodi statici.

super consente l’accesso a metodi e campi non privati ​​nella super-class e ad accedere ai costruttori solo dai costruttori della class.

Quando scrivi un codice, in genere non vuoi ripetere te stesso. Se hai una class che può essere costruita con vari numeri di parametri, una soluzione comune per evitare di ripetere te stesso è semplicemente chiamare un altro costruttore con valori predefiniti negli argomenti mancanti. C’è solo una fastidiosa limitazione a questo: deve essere la prima riga del costruttore dichiarato. Esempio:

 MyClass() { this(default1, default2); } MyClass(arg1, arg2) { validate arguments, etc... note that your validation logic is only written once now } 

Per quanto riguarda il costruttore super() , a differenza super.method() deve essere la prima riga del costruttore. Dopodiché è molto simile ai costruttori this() , DRY (Do not Repeat Yourself), se la class che estendi ha un costruttore che fa un po ‘di ciò che vuoi poi usarlo e poi continua con la costruzione del tuo object, ad esempio:

 YourClass extends MyClass { YourClass(arg1, arg2, arg3) { super(arg1, arg2) // calls MyClass(arg1, arg2) validate and process arg3... } } 

Informazioni aggiuntive:

Anche se non lo vedi, il costruttore di default senza argomenti chiama sempre super() . Esempio:

 MyClass() { } 

è equivalente a

 MyClass() { super(); } 

Vedo che molti hanno menzionato usando le parole chiave this e super su metodi e variabili – tutto bene. Ricorda solo che i costruttori hanno restrizioni esclusive sul loro utilizzo, il più notevole è che devono essere la prima istruzione del costruttore dichiarato e puoi usarne solo uno.

questa parola chiave usa chiamare il costruttore nella stessa class (altro costruttore sovraccarico)

syntax : questo (elenco di argomenti); // compatibile con la lista degli argomenti in altri costruttori nella stessa class

uso di parole chiave super per chiamare il costruttore nella super class.

syntax: super (lista di argomenti); // compatibile con l’ elenco di argomenti nel costruttore della super class.

Ex:

 public class Rect { int x1, y1, x2, y2; public Rect(int x1, int y1, int x2, int y2) // 1st constructor { ....//code to build a rectangle } } public Rect () { // 2nd constructor this (0,0,width,height) // call 1st constructor (because it has **4 int args**), this is another way to build a rectangle } public class DrawableRect extends Rect { public DrawableRect (int a1, int b1, int a2, int b2) { super (a1,b1,a2,b2) // call super class constructor (Rect class) } } 

super () e questo ()

  • super () – per chiamare il costruttore della class genitore.
  • this () – per chiamare il costruttore della stessa class.

NOTA:

  • Possiamo usare super () e this () solo nel costruttore non da nessun’altra parte, qualsiasi tentativo di farlo porterà ad errori in fase di compilazione.

  • Dobbiamo mantenere super () o this () come prima riga del costruttore ma NON entrambi contemporaneamente.

super e questa parola chiave

  • super – per chiamare i membri della class genitore (variabili e metodi).
  • questo – per chiamare membri della stessa class (variabili e metodi).

NOTA: Possiamo utilizzare entrambi in una class, ad eccezione delle aree statiche (blocco o metodo statico), qualsiasi tentativo di farlo porterà ad errori in fase di compilazione.

1. uso della parola chiave SUPER.

Se il metodo sostituisce uno dei metodi della sua superclass, puoi invocare il metodo sottoposto a override tramite l’uso della parola chiave super. Puoi anche usare super per fare riferimento a un campo nascosto (anche se i campi nascosti sono scoraggiati). Considera questa class, Superclass:

 public class Superclass { public void printMethod() { System.out.println("Printed in Superclass."); } 

}

Ecco una sottoclass, chiamata Sottoclass, che sovrascrive printMethod ():

 public class Subclass extends Superclass { // overrides printMethod in Superclass public void printMethod() { super.printMethod(); System.out.println("Printed in Subclass"); } public static void main(String[] args) { Subclass s = new Subclass(); s.printMethod(); } 

}

All’interno di Sottoclass, il nome semplice printMethod () si riferisce a quello dichiarato in Sottoclass, che sovrascrive quello in Superclass. Quindi, per fare riferimento a printMethod () ereditato da Superclass, la sottoclass deve usare un nome qualificato, usando super come mostrato. Compilare ed eseguire Sottoclass stampa quanto segue:

Stampato in Superclass. Stampato in sottoclass.


2. uso di questa parola chiave Usando questo con un campo

Il motivo più comune per utilizzare la parola chiave this è perché un campo è ombreggiato da un metodo o un parametro del costruttore.

Ad esempio, la class Point è stata scritta in questo modo

 public class Point { public int x = 0; public int y = 0; //constructor public Point(int a, int b) { x = a; y = b; } 

}

ma potrebbe essere stato scritto in questo modo:

 public class Point { public int x = 0; public int y = 0; //constructor public Point(int x, int y) { this.x = x; this.y = y; } 

}

Ogni argomento del costruttore ombreggia uno dei campi dell’object – all’interno del costruttore x è una copia locale del primo argomento del costruttore. Per fare riferimento al campo Punto x, il costruttore deve utilizzare questo.x.

Usando questo con un Costruttore

Dall’interno di un costruttore, puoi anche usare la parola chiave this per chiamare un altro costruttore nella stessa class. Ciò si chiama chiamata esplicita del costruttore. Ecco un’altra class Rectangle, con un’implementazione diversa da quella nella sezione Oggetti.

 public class Rectangle { private int x, y; private int width, height; public Rectangle() { this(0, 0, 0, 0); } public Rectangle(int width, int height) { this(0, 0, width, height); } public Rectangle(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; } 

}

Questa class contiene un insieme di costruttori. Ogni costruttore inizializza alcune o tutte le variabili membro del rettangolo. I costruttori forniscono un valore predefinito per qualsiasi variabile membro il cui valore iniziale non è fornito da un argomento. Ad esempio, il costruttore no-argument chiama il costruttore a quattro argomenti con quattro valori 0 e il costruttore a due argomenti chiama il costruttore a quattro argomenti con due valori 0. Come prima, il compilatore determina quale costruttore chiamare, in base al numero e al tipo di argomenti.

Se presente, l’invocazione di un altro costruttore deve essere la prima riga nel costruttore.

Sembra quasi che si tratti di una situazione in cui una persona ha posto una domanda a cui tutti vedono solo una ansible risposta. Eppure la persona chiama ogni risposta come una non risposta, quindi ognuno prova una variante diversa sulla stessa risposta poiché sembra che ci sia solo un modo per rispondere.

Quindi, una persona inizia con A è una class e B è la sua sottoclass. La prossima persona inizia con C è una Classe e B è la sua sottoclass. Una terza persona risponde in modo un po ‘diverso. A è una class e B estende A. Quindi una quarta dice che A è una class che si estende quando B è definito. Oppure Animal è una class e Dog è una sottoclass. O la nazione è una class e la Cina è un caso speciale di nazione.

O meglio ancora, Man è una class, e Clark Kent è una sottoclass di Man. Quindi, Superman … no … non funziona in termini di Java ….

Bene, è almeno un altro tentativo di fornire una descrizione diversa che nessuno ha inventato per spiegare le cose in modo diverso. Arggghhhh.

Mi sembra che la spiegazione di tutti abbia funzionato tranne la mia.