W dziedziczeniu dlaczego konstruktor klasy podstawowej najpierw otrzymuje wywołanie, dlaczego nie pochodzi?Dlaczego konstruktor jest wywoływany w odwrotnej kolejności?
Odpowiedz
Aby upewnić się, że publiczni lub chronieni członkowie klasy bazowej są poprawnie zainicjowani, zanim zostaną zastosowani w klasie pochodnej.
Precyzyjnie, konstruktor klasy pochodnej jest uruchamiany jako pierwszy z niejawnym wywołaniem do konstruktora klasy podstawowej wstawionego jako pierwsza instrukcja w treści konstruktora klasy pochodnej przez kompilator (przyjmując domyślne konstruktory bez-arg).
Klasa pochodna jest tworzona przez rozszerzenie klasy bazowej. Należy upewnić się, że członkowie klasy podstawowej są poprawnie zainicjowani, zanim będzie można ich rozszerzyć w klasie pochodnej. Ponadto członkowie inicjowani w klasie pochodnej nie powinni być nadpisywani przez klasę podstawową.
Co rodzi się pierwszy, rodzic lub dziecko?
Zastanów się, co mogłoby się stać, gdyby było odwrotnie. Wyobraźmy sobie klasę użytkownika o wartości _id
. _id
z 0 jest specjalnymi wartościami, które reprezentują konto "gościa" (zignoruj problemy wokół "wartości specjalnych", po pierwsze nie zawsze są złym pomysłem, a po drugie jest to tylko przykład). _id
również nie może zostać zmieniony po zbudowaniu (co ma sens, jeśli można go zmienić nie jest już tak naprawdę identyfikatorem).
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; }
}
}
Teraz należy rozważyć klasę Admin, która podklasuje od tego. Jedną z zasad klasy Admin jest to, że gość nigdy nie może być administratorem. Ta niezmienna powinny być egzekwowane we wszystkich punktach status gość może się zmienić, co w tym przypadku jest tylko w konstruktorze:
public class Admin : User
{
public Admin(int id)
:base(id)
{
if(IsGuest)
throw new SecurityException("Guest users cannot be admins.");
}
}
Jeśli Admin
został zbudowany przed User
wtedy zawsze rzucić ten wyjątek, gdyż badanie zawsze porównaj 0 z 0. Gdybyśmy mieli inną specjalną wartość dla gości, to byłoby jeszcze gorzej i nigdy nie wyrzucajmy wyjątku nawet wtedy, gdy powinien, i pozwól na problem z bezpieczeństwem.
Należy pamiętać, że osoba pisząca klasę Admin
nie musi mieć żadnej wiedzy o tym, jak działa User
poza tym, co jest udokumentowane na temat jego publicznego i chronionego interfejsu. Mogą oni uchwycić powyższy problem, dodając własny test na to, czy id
ma wartość zero, czy nie, ale oprócz tego, że jest to niepotrzebne powielanie kodu, nie ma powodu, dla którego powinni wiedzieć, w jaki sposób działa sprawdzanie IsGuest
i może być o wiele bardziej skomplikowane. niż jest powyżej, a może być zastrzeżonym, zaciemnionym i nieudokumentowanym.
Bardziej ogólna koncepcja "konstruowania administratora" nie ma sensu bez koncepcji "konstruowania użytkownika" jako czegoś, co wydarzyło się jako pierwsze, nie możemy stworzyć bardziej wyspecjalizowanego typu X bez tworzenia X jako warunek wstępny.
- 1. Dlaczego wywoływany jest konstruktor ruchu?
- 2. Dlaczego ten konstruktor kopiowania jest wywoływany, a nie konstruktor ruchu?
- 3. os.walk() w odwrotnej kolejności?
- 4. TemplateBeginRepeat w odwrotnej kolejności
- 5. Który konstruktor jest tutaj wywoływany?
- 6. Dlaczego wywoływany jest domyślny konstruktor w dziedziczeniu wirtualnym?
- 7. odwrotnej kolejności zestaw elementów
- 8. Android - FirebaseListAdapter w odwrotnej kolejności?
- 9. Sortowanie NSArray w odwrotnej kolejności
- 10. Sortuj listę w odwrotnej kolejności
- 11. Dlaczego zamiast konstruktora konwersji wywoływany jest konstruktor kopiowania?
- 12. "Brak odpowiedniego domyślnego konstruktora" - Dlaczego wywoływany jest domyślny konstruktor?
- 13. Dlaczego .Net Native kompiluje pętlę w odwrotnej kolejności?
- 14. Dlaczego libstdC++ przechowuje elementy std :: tuple w odwrotnej kolejności?
- 15. strpos funkcja w odwrotnej kolejności w php
- 16. Flash - Odtwórz film w odwrotnej kolejności?
- 17. Dlaczego konstruktor kopiowania wywoływany w wywołaniu std :: vector :: emplace_back()?
- 18. Dlaczego wywoływany jest destruktor przeniesionego obiektu?
- 19. Jak sortować IntStream w odwrotnej kolejności
- 20. Praca z seriami w odwrotnej kolejności (najnowsze)
- 21. usort zwraca tablicę w odwrotnej kolejności
- 22. Konstruktor nie jest wywoływany w rozszerzonym DOMENIE PHP
- 23. Dlaczego PostConstruct nie jest wywoływany?
- 24. Statyczny konstruktor jest wywoływany dwa razy w tym samym appdomain?
- 25. Dlaczego wywoływany jest python destructor?
- 26. Czy destruktor jest wywoływany podczas rzucania konstruktora delegującego?
- 27. funkcja zwraca listę w odwrotnej kolejności w OCaml
- 28. Dlaczego konstruktor kopiowania nie jest wywoływany, gdy zwracana wartość-wartość jest obiektem inicjowanym listą?
- 29. Czy zmienne stosu C są przechowywane w odwrotnej kolejności?
- 30. Dlaczego konstruktor ruchu nie jest wywoływany podczas poruszania się w lambda?
Zobacz: http://stackoverflow.com/questions/140490/base-constructor-in-c-which-gets-called-first, http://stackoverflow.com/questions/1882692/c-constructor-execution -zamówienie –