2012-12-13 21 views
5

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#

+4

"Teraz sądzę, że możemy zastąpić metody nawet bez użycia słowa kluczowego" wirtualne "." Myślisz? – BoltClock

+2

@BoltClock Z pewnością. 'abstract' w klasie bazowej i' override' w klasie pochodnej wystarczą. Nie ma potrzeby "wirtualnego": P – CodesInChaos

+1

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. –

Odpowiedz

11

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"!!! 
2

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.

7

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.

1

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 i override 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.

Powiązane problemy