Jakie są różnice między zadeklarowaniem metody w typie podstawowym „ virtual
”, a następnie nadpisaniem jej w typie podrzędnym za pomocą override
słowa kluczowego „ ”, a nie po prostu za pomocą new
słowa kluczowego „ ” w przypadku zadeklarowania metody dopasowania w typie podrzędnym?
c#
syntax
overriding
method-hiding
member-hiding
i3ensays
źródło
źródło
new
tworzy nowego członka o tej samej nazwie i powoduje, że oryginalny członek zostaje ukryty, a jednocześnieoverride
rozszerza implementację dla odziedziczonego członka”Odpowiedzi:
Słowo kluczowe „new” nie zastępuje, oznacza nową metodę, która nie ma nic wspólnego z metodą klasy podstawowej.
Wypisuje to fałsz, jeśli użyjesz przesłonięcia, wydrukowałoby to prawda.
(Kod podstawowy pochodzi od Josepha Daigle'a)
Tak więc, jeśli robisz prawdziwy polimorfizm, POWINNO ZAWSZE BYĆ NADMIERNE . Jedynym miejscem, w którym należy użyć „nowego”, jest to, że metoda nie jest w żaden sposób powiązana z wersją klasy podstawowej.
źródło
virtual
w podstawie ioverride
w pochodzić? Dlaczego to istnieje? Kod nadal będzie działał nawet beznew
- więc czy jest to czysta czytelność?Zawsze znajduję takie rzeczy łatwiejsze do zrozumienia na zdjęciach:
Ponownie, biorąc kod Josepha Daigle'a,
Jeśli następnie wywołasz kod w ten sposób:
UWAGA: Ważną rzeczą jest to, że nasz obiekt jest tak naprawdę
Bar
, ale przechowujemy go w zmiennej typuFoo
(jest to podobne do rzutowania)Wynik będzie następujący, w zależności od tego, czy używałeś
virtual
/override
lubnew
deklarując swoje zajęcia.źródło
Oto kod, aby zrozumieć różnicę w zachowaniu metod wirtualnych i nie-wirtualnych:
źródło
new
po co „ukrywać” metodę podstawową, skoro po prostu nie zastępowanie wydaje się robić to samo?virtual
a kompilator będzie narzekał, jeśli zobaczy tę samą nazwę funkcji w klasie „linia krwi” bezvirtual
podpisuSłowo
new
kluczowe faktycznie tworzy całkowicie nowego członka, który istnieje tylko dla tego określonego typu.Na przykład
Metoda istnieje na obu typach. Kiedy użyjesz refleksji i uzyskasz elementy typu
Bar
, w rzeczywistości znajdziesz 2 nazywane metody,DoSomething()
które wyglądają dokładnie tak samo. Korzystając z niegonew
, skutecznie ukrywasz implementację w klasie bazowej, aby gdy klasy wywodzą sięBar
(w moim przykładzie), wywołanie metody dobase.DoSomething()
idzie,Bar
a nieFoo
.źródło
virtual / override informuje kompilator, że obie metody są ze sobą powiązane, i że w niektórych okolicznościach, gdy wydaje ci się, że wywołujesz pierwszą (wirtualną) metodę, to w rzeczywistości poprawne jest wywołanie drugiej (zastąpionej) metody. To podstawa polimorfizmu.
Wywoła nadpisaną metodę VirtualFoo () podklasy.
new informuje kompilator, że dodajesz metodę do klasy pochodnej o takiej samej nazwie jak metoda w klasie bazowej, ale nie mają one ze sobą żadnego związku.
Wywoła metodę NewBar () klasy BaseClass, podczas gdy:
Wywoła metodę NewBar () SubClass.
źródło
Poza szczegółami technicznymi myślę, że użycie wirtualnego / zastępowania przekazuje wiele semantycznych informacji o projekcie. Deklarując metodę wirtualną, wskazujesz, że oczekujesz, że klasy implementujące mogą chcieć udostępnić własne, niestandardowe implementacje. Pominięcie tego w klasie podstawowej również deklaruje oczekiwanie, że domyślna metoda powinna wystarczyć dla wszystkich klas implementujących. Podobnie, można użyć deklaracji abstrakcyjnych, aby zmusić klasy implementujące do zapewnienia własnej implementacji. Ponownie myślę, że to dużo mówi o tym, jak programista oczekuje użycia kodu. Gdybym pisał zarówno klasę podstawową, jak i implementacyjną i znalazłem się przy użyciu nowych, poważnie przemyślałem decyzję, aby nie uczynić tej metody wirtualną w obiekcie nadrzędnym i konkretnie zadeklarować swój zamiar.
źródło
Różnica między zastąpionym słowem kluczowym a nowym słowem kluczowym polega na tym, że pierwsze z nich zastępuje metodę, a później ukrywa metodę.
Więcej informacji znajdziesz w poniższych linkach ...
MSDN i inne
źródło
new
słowo kluczowe służy do ukrywania. - oznacza, że ukrywasz swoją metodę w czasie wykonywania. Dane wyjściowe będą oparte na metodzie klasy bazowej.override
do zastąpienia. - oznacza, że wywołujesz metodę klasy pochodnej z referencją do klasy bazowej. Dane wyjściowe będą oparte na metodzie klasy pochodnej.źródło
Moja wersja wyjaśnień pochodzi z używania właściwości, które pomagają zrozumieć różnice.
override
jest dość proste, prawda? Typ podstawowy zastępuje typ rodzica.new
jest może mylące (dla mnie tak było). Dzięki właściwościom łatwiej jest zrozumieć:Za pomocą debugera można zauważyć, że
Foo foo
ma 2GetSomething
właściwości, ponieważ tak naprawdę ma 2 wersje właściwości,Foo
iBar
, i aby wiedzieć, który z nich użyć, c # „wybiera” właściwość dla bieżącego typu.Jeśli chcesz użyć wersji paska, użyłbyś zastąpienia lub użycia
Foo foo
zamiast tego.Bar bar
ma tylko 1 , ponieważ chce zupełnie nowego zachowaniaGetSomething
.źródło
Brak oznaczenia metody w jakikolwiek sposób oznacza: Powiąż tę metodę, używając typu kompilacji obiektu, a nie typu wykonawczego (wiązanie statyczne).
Oznaczanie metody za pomocą
virtual
pomocą środków: Powiąż tę metodę, używając typu środowiska wykonawczego obiektu, a nie typu czasu kompilacji (dynamiczne wiązanie).Oznaczenie
virtual
metody klasy bazowej za pomocąoverride
w klasie pochodnej oznacza: Jest to metoda, którą należy powiązać przy użyciu typu środowiska wykonawczego obiektu (powiązanie dynamiczne).Oznaczenie
virtual
metody klasy bazowej w klasienew
pochodnej oznacza: Jest to nowa metoda, która nie ma związku z tą o tej samej nazwie w klasie bazowej i powinna być powiązana przy użyciu typu czasu kompilacji obiektu (wiązanie statyczne).Brak oznaczenia
virtual
metody klasy bazowej w klasie pochodnej oznacza: Ta metoda jest oznaczona jakonew
(wiązanie statyczne).Oznaczenie metody
abstract
oznacza: Ta metoda jest wirtualna, ale nie zadeklaruję dla niej treści, a jej klasa jest również abstrakcyjna (wiązanie dynamiczne).źródło