Costruttori e ereditarietà predefiniti in Java

Ho una domanda sui costruttori e sull’ereditarietà predefiniti in Java.

In genere, se si scrive una class e non si include alcun costruttore, Java fornisce automaticamente un costruttore predefinito (uno senza parametri), che inizializza tutte le variabili di istanza della class (se presenti) con alcuni valori predefiniti (0, null o falso). Se si scrive un costruttore, tuttavia, con alcuni parametri e non si scrive alcun costruttore predefinito, Java non fornisce un costruttore predefinito. La mia domanda è: qual è il caso delle classi, che ereditano da altre classi – se scrivo un costruttore con alcuni parametri al loro interno, ma non includo un costruttore predefinito, ereditano il costruttore predefinito della super-class?

  1. Se non si crea un costruttore, viene automaticamente creato il costruttore vuoto predefinito .

  2. Se un costruttore non richiama esplicitamente un super o questo costruttore come prima istruzione, viene automaticamente aggiunta una chiamata a super () .

Sempre.

I costruttori non sono ereditati.

Inoltre, l’inizializzazione dei campi viene eseguita dalla macchina virtuale, non dal costruttore predefinito. Il costruttore predefinito invoca semplicemente il costruttore predefinito della superclass e il costruttore predefinito di Object è vuoto. Il punto buono di questo design è che non c’è modo di accedere mai ai campi non inizializzati.

A meno che non si usi super (…) un costruttore chiama il costruttore vuoto del suo genitore. Nota: lo fa su tutte le classi, anche su quelle che estendono l’object.

Questo non è ereditario, le sottoclassi non ottengono gli stessi costruttori con gli stessi argomenti. Tuttavia, puoi aggiungere costruttori che chiamano uno dei costruttori della super class.

La regola di base è una chiamata (o invocazione) a un costruttore che dovrebbe essere la prima affermazione che JVM deve eseguire,

Quindi, quando si ha una super class con solo costruttore parametrizzato e nessun costruttore predefinito, e la class base non ha alcuna chiamata esplicita al costruttore parametrizzato della super class, JVM fornisce il super (); chiamata che genera un errore in quanto non esiste un costruttore predefinito per la super class, quindi forniamo un costruttore predefinito nella super class o chiamiamo esplicitamente il costruttore parametrico della super class nel costruttore della class base. quando diamo la chiamata esplicita, quindi JVM non si preoccupa di mettere la linea super (); come invocazione del costruttore dovrebbe essere la prima affermazione del metodo, che non può avvenire (a causa della nostra chiamata esplicita).

La Sezione 8.8.9 della Specifica del linguaggio Java spiega in dettaglio cosa sta succedendo:

Se una class non contiene dichiarazioni del costruttore, allora un costruttore predefinito viene dichiarato implicitamente. La forma del costruttore predefinito per una class di livello superiore, class membro o class locale è la seguente:

  • Il costruttore predefinito ha la stessa accessibilità della class (§6.6).
  • Il costruttore predefinito non ha parametri formali, ad eccezione di una class membro interna non privata, in cui il costruttore predefinito dichiara implicitamente un parametro formale che rappresenta l’istanza immediatamente allegata della class (§8.8.1, §15.9.2, §15.9.3 ).
  • Il costruttore predefinito non ha clausole di ricaduta.
  • Se la class che viene dichiarata è l’object di class primordiale, il costruttore predefinito ha un corpo vuoto. Altrimenti, il costruttore predefinito invoca semplicemente il costruttore della superclass senza argomenti.

Puoi vedere che non c’è nessuna eredità in corso qui: tutto quello che c’è da fare è la “magia del compilatore” con il costruttore predefinito implicitamente dichiarato. La specifica chiarisce anche che il costruttore predefinito viene aggiunto solo quando la class non ha costruttori, il che significa che la risposta alla tua domanda è “no”: una volta assegnato a una class un costruttore, l’accesso al costruttore predefinito della sua la superclass è persa.

Se si fornisce un costruttore, Java non genererà un costruttore vuoto predefinito. Quindi la tua class derivata sarà in grado di chiamare il tuo costruttore.

Il costruttore predefinito non inizializza le tue variabili private ai valori predefiniti. La dimostrazione è che è ansible scrivere una class che non ha un costruttore predefinito e ha i suoi membri privati ​​inizializzati su valori predefiniti. Ecco un esempio:

 public class Test { public String s; public int i; public Test(String s, int i) { this.s = s; this.i = i; } public Test(boolean b) { // Empty on purpose! } public String toString() { return "Test (s = " + this.s + ", i = " + this.i + ")"; } public static void main (String [] args) { Test test_empty = new Test(true); Test test_full = new Test("string", 42); System.out.println("Test empty:" + test_empty); System.out.println("Test full:" + test_full); } } 

Thumb Rule è che la Sottoclass dovrebbe chiamare qualsiasi costruttore dalla class base. quindi se non hai il const predefinito, chiama quello esistente da sottoclass. altri saggi implementano il const vuoto nella class base per evitare il problema di compilazione

La risposta alla tua domanda è molto semplice. Implicitamente (invisibile), la prima affermazione in qualsiasi costruttore è ‘super ();’ cioè la chiamata al costruttore di parametri senza super-class, finché non la cambi esplicitamente in qualcosa come ‘this ();’, ‘this (int)’, ‘this (String)’, ‘super (int)’, ‘super (String ) ‘ecc.’ questo (); ‘ è il costruttore della class corrente.

Quando non creiamo un costruttore, Java crea automaticamente un costruttore predefinito. Ma quando creiamo uno o più costruttori personalizzati con argomenti, Java non crea costruttori predefiniti. Se creiamo uno o più costruttori e vogliamo creare un object senza alcun argomento di costruzione, dobbiamo dichiarare un costruttore vuoto.

Ci sarà un errore in fase di compilazione … perché il compilatore cerca Costruttore di default che Superclass e se non è lì … è un errore … e il programma non verrà compilato …