Posiadam znajomość java i uczyłem się C# przez ostatnie kilka dni. Teraz natknąłem się na "wirtualne" słowo kluczowe, które zgodnie z sugestią pod numerem this link, pozwala na zastąpienie odpowiednich metod, właściwości itp. W podklasach. Teraz myślę, że możemy przesłonić metody nawet bez użycia słowa kluczowego "wirtualny". Więc dlaczego jest to konieczne?wirtualne słowo kluczowe w języku C#
Odpowiedz
Potrzebujesz słowa kluczowego virtual
, jeśli naprawdę chcesz override
metod w podklasach. W przeciwnym razie implementacja podstawowa zostanie ukryta w nowej implementacji, tak jakbyś zadeklarował ją słowem kluczowym new
.
Ukrywanie metod przez "przesłonięcie" ich bez deklaracji metody bazowej virtual
pozostawia cię bez polimorfizmu, co oznacza: jeśli "wyrzucisz" wersję specjalistyczną do wersji "bazowej" i wywołasz metodę, zawsze klasy bazowe implementacja zostanie zastosowana zamiast zastąpionej wersji - co nie jest tym, czego można się spodziewać.
przykład:
class A
{
public void Show() { Console.WriteLine("A"); }
}
class B : A
{
public void Show() { Console.WriteLine("B"); }
}
A a = new A();
B b = new B();
a.Show(); // "A"
b.Show(); // "B"
A a1 = b;
a1.Show(); // "A"!!!
Teraz myślę, że możemy zastąpić metody nawet bez użycia słowa kluczowego "wirtualny".
Nie, nie możesz. W przeciwieństwie do Javy, C# członkami są uszczelnione domyślnie i nie można zastąpić je, chyba że zaznaczono je ze słowem kluczowym virtual
.
to sposób zdefiniowania domyślnej implementacji metody, ale ta implementacja może zostać nadpisana w klasie potomnej. Inaczej niż przy użyciu wirtualnego, nie można przesłonić metody bezpośrednio, bez użycia słowa kluczowego new
(co jest ogólnie złą praktyką).
Dobrym przykładem wdrożenia virtual
jest metoda ToString()
. Każdy obiekt w języku C# ma zagwarantowaną możliwość wywołania ToString()
, ponieważ każdy obiekt dziedziczy z klasy podstawowej System.Object
, która zawiera wirtualną metodę ToString()
. Klasy pochodne mogą to jednak zmienić i zapewnić własną implementację, która może być bardziej przydatna dla użytkowników obiektu.
Aktualizacja: Niedawno napisałem na blogu, który przechodzi w tym temacie w trochę głębi. Check it out here.
Spójrz w tym np
void Main()
{
var o1 = new S();
Console.WriteLine(((B)o1).m1());
}
public class B
{
public virtual string m1() {
return "m1";
}
}
public class S : B
{
override public string m1() {
return "overridden m1";
}
}
W tym przykładzie podklasa S
jest tworzony i przypisany do obiektów o zmiennej o1
. W Parametr Console.WriteLine
komunikat za to jest wrzucony do klasy bazowej B
, wówczas metoda m1
nazywa. Ponieważ użyliśmy virtual
w klasie bazowej B
i override
w podklasie S
, jesteśmy coraz
przesłonięta M1
jako wyjścia.Jeśli usuniesz virtual
w deklaracji metody m1
w B
i override
w podklasie S
wtedy dostajesz
m1
jako wyjście, co oznacza, że obsada ma również wpływ, jaki zastosowano oryginalną deklarację metody m1
w klasie bazowej B
.
N.B. Jeśli używasz słowa kluczowego new
w podklasie S
, takich jak
new public string m1() {
return "overridden m1";
}
zakładając, że virtual
kluczowe w klasie bazowej B
jest nieobecny, dostajesz wyjście
m1
również. Jeśli nie chcesz go rzucić na B
, użyjemy nowej metody. To jest nazywane shadowing (lub ukrywanie) metody (oryginalnej metody z klasy bazowej).
Podsumowanie:
Aby zastąpić metodę, która powinna być skuteczna także jeśli oddanych do klasy bazowej, użyj
virtual
słowa kluczowego w klasie bazowej ioverride
w klasie sub.Jeśli zamierzasz zastąpić metodę, która powinna być aktywna tylko w podklasie, użyj słowa kluczowego
new
w deklaracji metody podklas. Jak widzieliście, działa również bez niego, ale lepiej, jeśli jest, więc każdy wie, że jest to nowa wersja tej metody.
- 1. Co dokładnie robi słowo kluczowe "using" w języku C++?
- 2. C# - Wyłącz dynamiczne słowo kluczowe
- 3. EntityFramework CTP5 DbContext T4 Szablon "wirtualne" słowo kluczowe
- 4. Przeciwne słowo kluczowe "restrict" w C?
- 5. użycie "to" słowo kluczowe w C++
- 6. Kiedy słowo kluczowe "inline" działa w C?
- 7. "Istnieje" słowo kluczowe w Pythonie?
- 8. Co robi słowo wirtualne w actionscript?
- 9. Czyste metody wirtualne w języku C#?
- 10. Co oznacza słowo wirtualne podczas przesłaniania metody?
- 11. C# params słowo kluczowe i funkcja przeciążenia
- 12. Dynamiczne słowo kluczowe C# 4 - dlaczego nie?
- 13. W języku Java, dlaczego jest słowo kluczowe, a nie metoda?
- 14. Co oznacza słowo kluczowe fileprivate w języku Swift?
- 15. Go „to” -słowo kluczowe
- 16. Dlaczego jest 'to' słowo kluczowe nie rodzaj odniesienia w C++
- 17. „jako” słowo kluczowe w SML
- 18. Wielokrotne powtórzone słowo kluczowe "w"
- 19. JavaScript "argumenty" Słowo kluczowe
- 20. Jak wymusić słowo kluczowe "zastąp"?
- 21. Słowo kluczowe "ref" i AppDomains
- 22. "nowe" słowo kluczowe w deklaracji nieruchomości w C#
- 23. Słowo kluczowe "klasa" w definicji zmiennej w C++
- 24. Czy istnieje słowo kluczowe w języku C#, które spowodowałoby, że zmienne lokalne pozostałyby w wielu połączeniach?
- 25. Słowo kluczowe wyrzucania w sygnaturze funkcji
- 26. Czy null to słowo kluczowe Java?
- 27. Słowo kluczowe (LUB, AND) szukaj w Lucene
- 28. Wiążące słowo kluczowe odnosi się do czego?
- 29. Do czego służy słowo kluczowe "zastąp" w C++?
- 30. Co oznacza słowo kluczowe "i" w Objective-C?
"Teraz sądzę, że możemy zastąpić metody nawet bez użycia słowa kluczowego" wirtualne "." Myślisz? – BoltClock
@BoltClock Z pewnością. 'abstract' w klasie bazowej i' override' w klasie pochodnej wystarczą. Nie ma potrzeby "wirtualnego": P – CodesInChaos
Tak, wirtualny oznacza "Dostarczam implementację, ale możesz ją przesłonić polimorficznie", a streszczenie oznacza "Definiuję coś, na co musisz podać implementację, która będzie działać polimorficznie". W przeciwieństwie do shadowingu (który jest ogólnie uważany za nieoptymalny), sygnatury funkcji muszą być zgodne. –