Nell'ereditarietà perché il costruttore della classe base riceve prima la chiamata, perché non quella derivata ??Perché il costruttore viene chiamato nell'ordine inverso?
risposta
Per assicurarsi che i membri pubblici o protetti della classe base siano correttamente inizializzati prima di essere utilizzati nella classe derivata.
Per essere precisi, il costruttore della classe derivata viene eseguito prima con una chiamata implicita al costruttore della classe base inserito come prima istruzione nel corpo del costruttore della classe derivata dal compilatore (assumendo i costruttori no-arg predefiniti).
La classe derivata viene creata estendendo la classe base. È necessario assicurarsi che i membri della classe base siano inizializzati correttamente, prima che possano essere estesi in una classe derivata. Inoltre, i membri inizializzati nella classe derivata non devono essere sovrascritti dalla classe base.
Che cosa nasce prima, il genitore o il bambino?
Considerate cosa potrebbe accadere se fosse il contrario. Immaginiamo una classe utente con un valore _id
. Lo _id
di 0 è un valore speciale che rappresenta un account "guest" (ignora i problemi relativi ai "valori speciali", in primo luogo non sono sempre una cattiva idea, e in secondo luogo questo è solo un esempio). Il _id
non può anche essere modificato dopo la costruzione (il che ha senso, se può essere cambiato non è più un identificatore).
public class User
{
private readonly int _id;
public User(int id)
{
_id = id;
}
public int ID
{
get { return _id; }
}
public bool IsGuest
{
get { return _id == 0; }
}
}
Considerare ora una classe di amministrazione che sottoclassi da questo. Una delle regole della classe Admin è che un guest non può mai essere un amministratore. Questo invariante dovrebbe essere applicata in tutti i punti dello stato ospite può cambiare, che in questo caso è solo nel costruttore:
public class Admin : User
{
public Admin(int id)
:base(id)
{
if(IsGuest)
throw new SecurityException("Guest users cannot be admins.");
}
}
Se Admin
è stato costruito prima del User
allora sarebbe sempre buttare questa eccezione, come il test sarebbe sempre confronta 0 con 0. Se avessimo un valore speciale diverso per gli ospiti, sarebbe anche peggio, e non lanciare mai l'eccezione anche quando dovrebbe, e consentire un problema di sicurezza.
Tenere presente anche che la persona che scrive la classe Admin
non deve avere alcuna conoscenza di come User
funzioni oltre quanto documentato sulla sua interfaccia pubblica e protetta. Potrebbero captare il problema sopra aggiungendo il proprio test per verificare se id
è zero o no, ma a parte il fatto che si tratta di una inutile duplicazione del codice, non c'è motivo per cui debbano sapere come funziona il controllo IsGuest
, e potrebbe essere molto più complicato che è sopra, e forse forse proprietario, offuscato e non documentato.
Più in generale, l'intero concetto di "costruzione di un amministratore" non ha senso senza il concetto di "costruzione di un utente" come qualcosa che è accaduto per prima, non possiamo creare un tipo più specializzato di X senza creare una X come un prerequisito.
- 1. Perché il mio costruttore di C++ sovraccarico non viene chiamato?
- 2. Perché il costruttore di movimento non viene chiamato?
- 3. Perché il costruttore viene chiamato una sola volta?
- 4. Il costruttore base non viene chiamato
- 5. Quando viene chiamato il costruttore in java?
- 6. Quando il costruttore di movimento viene chiamato
- 7. Perché viene chiamato questo costruttore di copia anziché il costruttore di mosse?
- 8. Perché viene chiamato il costruttore della copia invece del costruttore di movimento?
- 9. Perché il costruttore non viene chiamato quando() viene utilizzato per dichiarare un oggetto?
- 10. Perché viene chiamato $ HTTP_RAW_POST_DATA?
- 11. Vai: Perché il rinvio del ciclo di intervallo viene chiamato in ordine inverso?
- 12. Il costruttore di default C++ non viene chiamato
- 13. perché il mio onPrepareOptionsMenu non viene chiamato?
- 14. Perché il ContentObserver viene chiamato più volte?
- 15. Perché copiare il costruttore non viene richiamato?
- 16. Il costruttore non viene chiamato dall'oggetto risposta SOAP
- 17. Il costruttore/distruttore definito da tratto non viene chiamato
- 18. Quando viene chiamato il costruttore di hub SignalR?
- 19. Perché il costruttore viene chiamato se la classe ha un metodo (funzione) con il suo nome?
- 20. willTransitionToTraitCollection non viene chiamato, perché?
- 21. Perché GetVaryByCustomString non viene chiamato
- 22. perché textFieldDidEndEditing: non viene chiamato?
- 23. Perché PostConstruct non viene chiamato?
- 24. Perché non viene chiamato onBackPressed()?
- 25. Perché non viene chiamato -didDeselectRowAtIndexPath?
- 26. Perché il distruttore ha chiamato più del costruttore?
- 27. perché viene chiamato il costruttore di copie quando si passa temporaneamente da riferimento const?
- 28. Costruttore statico chiamato dopo il costruttore di istanze?
- 29. Il metodo virtuale non viene chiamato
- 30. che il costruttore della classe String viene chiamato quando oggetto String viene creato utilizzando String letterale
Vedere: http://stackoverflow.com/questions/140490/base-constructor-in-c-which-gets-called-first, http://stackoverflow.com/questions/1882692/c-constructor-execution -ordine –