Dziwię się, że wydaje się, że istnieje taki konsensus, że domyślnie niewirtualny jest właściwym sposobem robienia rzeczy. Zejdę po drugiej - myślę pragmatycznie - stronie ogrodzenia.
Większość uzasadnień brzmi dla mnie jak stary argument „Jeśli damy ci siłę, możesz się skrzywdzić”. Od programistów ?!
Wydaje mi się, że programista, który nie wiedział wystarczająco dużo (lub nie miał wystarczająco dużo czasu), aby zaprojektować swoją bibliotekę pod kątem dziedziczenia i / lub rozszerzalności, jest koderem, który stworzył dokładnie taką bibliotekę, którą prawdopodobnie będę musiał naprawić lub ulepszyć - dokładnie biblioteka, w której najbardziej przydatna byłaby możliwość nadpisania.
Ile razy musiałem napisać brzydki, desperacki kod obejścia (lub zrezygnować z użycia i wprowadzić własne alternatywne rozwiązanie), ponieważ nie mogę nadpisać daleko, znacznie przewyższa liczbę razy, kiedy byłem kiedykolwiek ugryziony ( np. w Javie), nadpisując, gdy projektant mógł nie rozważyć, że mogę.
Domyślnie niewirtualny utrudnia mi życie.
AKTUALIZACJA: Wskazano [całkiem poprawnie], że tak naprawdę nie odpowiedziałem na pytanie. A więc - i przepraszam za spóźnienie ....
Chciałem móc napisać coś zwięzłego, np. „C # domyślnie implementuje metody jako niewirtualne, ponieważ podjęto złą decyzję, która ceniła programy bardziej niż programiści”. (Myślę, że można to nieco uzasadnić na podstawie niektórych innych odpowiedzi na to pytanie - takich jak wydajność (przedwczesna optymalizacja, ktoś?) Lub gwarantowanie zachowania klas).
Jednak zdaję sobie sprawę, że przedstawiłbym tylko swoją opinię, a nie ostateczną odpowiedź, której pragnie Stack Overflow. Z pewnością, pomyślałem, na najwyższym poziomie ostateczna (ale nieprzydatna) odpowiedź brzmi:
Domyślnie nie są wirtualne, ponieważ projektanci języka musieli podjąć decyzję i właśnie to wybrali.
Teraz domyślam się, że z dokładnego powodu, dla którego podjęli tę decyzję, nigdy ... och, czekaj! Zapis rozmowy!
Wydawałoby się więc, że odpowiedzi i komentarze tutaj dotyczące niebezpieczeństw związanych z zastępowaniem interfejsów API i potrzeby jawnego projektowania dziedziczenia są na właściwej drodze, ale wszystkim brakuje ważnego aspektu czasowego: głównym zmartwieniem Andersa było utrzymanie niejawnych klas lub API kontrakt między wersjami . Myślę, że bardziej interesuje go pozwolenie platformie .Net / C # na zmianę pod kodem, niż zmiana kodu użytkownika na platformie. (A jego „pragmatyczny” punkt widzenia jest dokładnym przeciwieństwem mojego, ponieważ patrzy z drugiej strony).
(Ale czy nie mogli po prostu wybrać domyślnie wirtualnego, a następnie posypać „ostatecznym” kodem? Może to nie to samo ... a Anders jest wyraźnie mądrzejszy ode mnie, więc pozwolę mu kłamać.)
this
odwołanie ma wartość null. Więcej informacji znajdziesz tutaj .