Perché i costruttori non possono essere ereditati in java?

Sono un principiante nel linguaggio di programmazione java, recentemente ho studiato che i costruttori non possono essere ereditati in Java, qualcuno può spiegare perché ?

Ho già letto questo link di C ++

In parole semplici, un costruttore non può essere ereditato, poiché nelle sottoclassi ha un nome diverso (il nome della sottoclass).

 class A { A(); } class B extends A{ B(); } 

Puoi fare solo:

 B b = new B(); // and not new A() 

I metodi, invece, sono ereditati con “lo stesso nome” e possono essere usati.

Per quanto riguarda il motivo: non avrebbe molto senso ereditare un costruttore, dal momento che il costruttore di class A significa creare un object di tipo A, e il costruttore di class B significa creare un object di class B.

Puoi comunque usare i costruttori dall’implementazione di A all’interno di B:

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

Quello di cui stai parlando è il livello della lingua Java. Se i costruttori fossero ereditati, ciò renderebbe imansible rendere la class privata. Come sappiamo, la visibilità del metodo non può essere declassata. Object class Object ha un costruttore senza argomenti e ogni class estende Object , quindi nel caso dell’ereditarietà del costruttore ogni class dovrebbe avere un costruttore senza argomenti. Ciò infrange i principi di OO.

Le cose sono diverse a livello di bytecode. Quando viene creato l’object, vengono chiamati due operatori:

  1. nuovo – alloca la memoria per l’object
  2. invokespecial – chiama il costruttore su un pezzo di memoria appena assegnato

Possiamo modificare il bytecode in modo che la memoria sia allocata per la class Child e il costruttore sia chiamato dalla class Parent. In questo caso possiamo dire che i costruttori sono ereditati. Una nota se non disattiviamo la verifica del codice byte, JVM genererà un’eccezione durante il caricamento della class. Possiamo farlo aggiungendo -noverify argomento -noverify .

Conclusione:

  1. I costruttori non sono ereditati a livello di lingua a causa dei principi OO
  2. I costruttori sono ereditati a livello di bytecode

Motivo menzionato nei documenti di Eredità

Una sottoclass eredita tutti i membri (campi, metodi e classi nidificate) dalla sua superclass. I costruttori non sono membri, quindi non sono ereditati da sottoclassi, ma il costruttore della superclass può essere invocato dalla sottoclass.

Puoi consultare i documenti di Fornire i costruttori per le tue lezioni

  • Un costruttore può essere chiamato solo con new . Non può essere chiamato come metodo.
  • Il nome del costruttore è identico al nome della class.

Quindi l’ereditarietà non è praticamente ansible in quanto tale. Tuttavia in un costrutto si potrebbero chiamare altri costruttori.

  • Nella stessa class usando this(...) ;
  • Della class estesa usando super(...) ;

Esempio

 class A { A() { } // Constructor A(int a) { } // Constructor A(boolean c) { } // Constructor } class B extends A { B() { this(3, 7); } B(int a) { super(); } B(String b) { super(7); } B(int a, int c) { // Calls super() implicitly } } A a = new B(8): 

Sfortunatamente non esiste la possibilità di utilizzare il costruttore di A per un booleano:

 B b = new B(true): // ERROR 

I design di linguaggio potrebbero aver implementato qualcosa come:

Generare per ogni costruttore pubblico nella class base, un costruttore con la stessa firma se tale costruttore non è già stato definito. Chiama super con gli stessi parametri. Chiama this() se esiste un costruttore predefinito.

Sembra un po ‘eccessivo il codice. E non è semplicemente un puntatore in una tabella di metodi virtuale, con la quale funziona l’ereditarietà / sovrascrittura del metodo.

I costruttori non sono membri di classi e solo i membri sono ereditati. Non puoi ereditare un costruttore. Cioè, non puoi creare un’istanza di una sottoclass usando un costruttore di una delle sue superclassi.

Risposta semplice Ho osservato che non è ansible richiamare o utilizzare i costruttori della class genitore direttamente nella class figlio, ma i metodi della class genitore possono essere utilizzati direttamente nella class figlio.

Nel caso in cui tu abbia un metodo in class figlio con lo stesso nome della class genitore in quel momento, devi usare solo la parola chiave “super” per invocare l’ambiguità di chiamata di risoluzione del metodo della class genitore.

“Per invocare” costruttore della class genitore nella class figlio è sempre necessaria la parola chiave “super”. Quindi i costruttori della class genitore non sono “direttamente disponibili” come i metodi della class genitore nella class figlia, quindi possiamo dire che i costruttori non possono essere ereditati.

Solo i campi, i metodi e le classi annidate sono le membra di qualsiasi class non costruttori. Una sottoclass eredita tutti i membri come (campi, metodi e classi nidificate) dalla sua superclass. I costruttori non sono membri, quindi non sono ereditati da sottoclassi, ma il costruttore della superclass può essere invocato dalla sottoclass.

No, i costruttori non saranno ereditati in sottoclass, anche se non è un membro statico, non sarà ereditato in sottoclass perché i costruttori non verranno caricati all’interno dell’object, ma sarà usato per creare l’object. I costruttori sono come un inizializzatore non statico

Le limitazioni sintattiche possono essere spesso aggirate nel caso in cui ci sia una ragione per una caratteristica in modo concettuale. Con questo, credo, la vera ragione per non supportare l’ereditarietà del costruttore non è dovuta a limiti sintattici ma piuttosto alla semantica.

Concettualmente l’ereditarietà fornisce un meccanismo per acquisire (o ereditare) un comportamento e molto probabilmente senza scrivere alcun pezzo di codice poiché il suo scopo è quello di fornire il riutilizzo del codice. Per una class figlia, non fa caso ad ereditare il comportamento di inizializzazione della sua class genitore. Dopo tutto, un comportamento ereditato trova il suo miglior utilizzo quando un chiamante esterno può usarlo senza sapere chi (nella catena padre) lo abbia effettivamente implementato. Come si può vedere, un chiamante difficilmente ha la possibilità di sapere come viene inizializzata una class genitore tramite la sua class figlia, non esiste alcun motivo discernibile per supportare l’ereditarietà per un costruttore (della class madre).

non puoi ereditare costruttori ma puoi ereditare il valore inizializzato in costruttore come

 class test1 { int a,b; test1(){ a = 100; b = 20; } } class test2 extends test1 { test2(){ // do something } } class test { public static void main(String[] args) { test2 t = new test2(); int a = ta; int b = tb; System.out.println(a+b); } }