Dlaczego miałbyś zadeklarować metodę jako „wirtualną”.
Jakie są zalety korzystania z wirtualizacji?
Wirtualnej modyfikator jest stosowany do oznaczenia, że sposób \ właściwość (ECT) może być modyfikowany w klasie pochodnej za pomocą sterowania ręcznego modyfikatora.
Przykład:
class A
{
public virtual void Foo()
//DoStuff For A
}
class B : A
{
public override void Foo()
//DoStuff For B
//now call the base to do the stuff for A and B
//if required
base.Foo()
}
Wirtualne umożliwia dziedziczącej klasie zastąpienie metody, której następnie używa klasa bazowa.
public class Thingy
{
public virtual void StepA()
{
Console.Out.WriteLine("Zing");
}
public void Action()
{
StepA();
Console.Out.WriteLine("A Thingy in Action.");
}
}
public class Widget : Thingy
{
public override void StepA()
{
Console.Out.WriteLine("Wiggy");
}
}
class Program
{
static void Main(string[] args)
{
Thingy thingy = new Thingy();
Widget widget = new Widget();
thingy.Action();
widget.Action();
Console.Out.WriteLine("Press any key to quit.");
Console.ReadKey();
}
}
Po uruchomieniu programu Twoje wyniki będą wyglądać następująco:
Zing
A Thingy in Action.
Wiggy
A Thingy in Action.
Zwróć uwagę, że chociaż Widget wywołał metodę Action () zdefiniowaną na poziomie Thingy, wewnętrznie Thingy nazywała metodę Widget's StepA ().
Podstawowa odpowiedź brzmi: daje spadkobiercom klasy większą elastyczność. Oczywiście musisz dobrze zaprojektować swoją klasę, inaczej może to spowodować małe spustoszenie.
Metoda wirtualna to typ metody, w której rzeczywiste wywołania metody zależą od typu środowiska uruchomieniowego obiektu bazowego.
Metoda niewirtualna to typ metody, w której rzeczywista wywoływana metoda zależy od typu odwołania obiektu w momencie wywołania metody.
Metody wirtualne w witrynie MSDN
źródło
Nawet jeśli nie planujesz wyprowadzać z klasy, oznaczenie metody wirtualnej może być konieczne, aby mockować klasę. Niektóre frameworki do pozorowania pozwalają tylko na mockowanie metod wirtualnych. Należy zauważyć, że metody implementujące interfejs są niejawnie wirtualne.
Używam RhinoMocks, które ma to ograniczenie i właśnie z tego powodu zacząłem oznaczać moje metody jako wirtualne. Dla mnie jest to prawdopodobnie największy powód do korzystania z metod wirtualnych, ponieważ przypadki dziedziczenia są znacznie rzadsze.
źródło
Metody wirtualne są podobne do metod abstrakcyjnych w klasach bazowych, z tym wyjątkiem, że ich implementacja w klasach pochodnych jest opcjonalna. Możesz również umieścić logikę w metodzie wirtualnej i zastąpić ją w klasach pochodnych.
źródło
Krótkie pytanie, krótka odpowiedź! Zakwalifikuj swoją metodę jako „wirtualną”, jeśli myślisz, że będziesz dziedziczyć klasę, do której należy.
Dłuższa odpowiedź: „wirtualne umożliwia przesłonięcie, nadanie metodzie innego znaczenia w klasie pochodnej.
źródło
Aby móc przesłonić to w dziedziczeniu klas.
Sprawdź wpis MSDN dla słowa kluczowego. To wyjaśnia to bardziej szczegółowo.
źródło
Nie trzeba dodawać, że metody wirtualne przydają się, gdy kod próbuje przestrzegać zasady Open Closed
Przeczytaj więcej o zasadzie otwartej i zamkniętej tutaj , oryginalnym opracowaniu OCP wuja Boba.
Należy również pamiętać, że metody nie są domyślnie wirtualne w C # w przeciwieństwie do Java.
źródło
Tutaj jest to jasno wyjaśnione na przykładzie metody wirtualnej C #
źródło
Funkcje wirtualne to funkcje, które tak naprawdę nie istnieją. Klasa pochodna może modyfikować funkcję wirtualną, nadpisując ją. Funkcje wirtualne są jednym ze sposobów osiągnięcia polimorfizmu w czasie wykonywania
public class sample { public virtual void fun(){ Console.WriteLine("base sample class \n"); } } public class A : sample{ public override void fun(){ Console.WriteLine("Class A \n"); } } public class B : sample{ public override void fun(){ Console.WriteLine("Class B \n"); } } class run{ public static void main(String[] args){ sample obj = new sample(); sample obj1 = new A(); sample obj2 = new B(); obj.fun(); obj1.fun(); obj2.fun(); } }
źródło
public
modyfikatory dostępu Poclass A
iclass B
przyczyny błędów w czasie kompilacji. Dostępność elementów członkowskich w klasie bazowej z klasy pochodnej jest określana indywidualnie z klasy bazowej (domyślnie członkowie sąprivate
).Środowisko wykonawcze odbywa się w czasie kompilacji.
Gdy deklarujesz metodę jako wirtualną, zadeklarowanie jej w klasie pochodnej wymaga dodania modyfikatora
override
lubnew
.możemy to zobaczyć, kiedy
TrySpeak
. Podanie dziecka i ojca, obaj nazywają Mów o ojcu, podczas gdyTryScream
wywołują każdą metodę.Aby to zrozumieć, jest kilka rzeczy, które powinniśmy wiedzieć, w przypadku Child, Istnieją dwie
Scream
metody z klasy Child lub Father. Mogliśmy zadzwonić doScream
klasy Child lub Father. PonieważVirtaul
Modifier oznacza metodę, aby mogła być nadpisywana przez klasę pochodną, co oznacza, że nawet taScream
jest wywoływana z klasy Ojca, jest zastępowana, byłoby inaczej, gdybyś użył nowego modyfikatora.import system; class Father { Speak() { Console.Writeline("Father is speaking") } virtual Scream() { Console.Writeline("Father is screaming") } } class Child: father { Speak() { Console.Writeline("Child is speaking") } override Scream() { Console.Writeline("Child is screaming") } } class APP { public static void Main() { // We new two instances here Father father = new Father(); Child child = new Child(); // Here we call their scream or speak through TryScream or TrySpeak TrySpeak(father); TrySpeak(child); //>>>"Father is speaking" //>>>"Father is speaking" TryScream(father); TryScream(child); //>>>"Father is screaming" //>>>"Child is screaming" } // when your method take an Parameter who type is Father // You can either pass in a Father instance or // A instance of a derived Class from Father // which could be Child public static void TrySpeak(Father person) { person.Scream(); } public static void TryScream(Father person) { person.Speak(); } }
źródło
W języku C #, aby zastąpić metodę klasy bazowej w klasie pochodnej, musisz zadeklarować metodę klasy bazowej jako wirtualną, a metodę klasy pochodnej jako przesłonięcie, jak pokazano poniżej:
using System; namespace Polymorphism { class A { public virtual void Test() { Console.WriteLine("A::Test()"); } } class B : A { public override void Test() { Console.WriteLine("B::Test()"); } } class C : B { public override void Test() { Console.WriteLine("C::Test()"); } } class Program { static void Main(string[] args) { A a = new A(); B b = new B(); C c = new C(); a.Test(); // output --> "A::Test()" b.Test(); // output --> "B::Test()" c.Test(); // output --> "C::Test()" a = new B(); a.Test(); // output --> "B::Test()" b = new C(); b.Test(); // output --> "C::Test()" Console.ReadKey(); } } }
Można również mieszać ukrywanie metody i przesłanianie metody za pomocą słowa kluczowego virtual i new, ponieważ metoda klasy pochodnej może być jednocześnie wirtualna i nowa. Jest to wymagane, gdy chcesz dalej przesłonić metodę klasy pochodnej na następny poziom, ponieważ zastępuję metodę klasy B, Test () w klasie C, jak pokazano poniżej:
using System; namespace Polymorphism { class A { public void Test() { Console.WriteLine("A::Test()"); } } class B : A { public new virtual void Test() { Console.WriteLine("B::Test()"); } } class C : B { public override void Test() { Console.WriteLine("C::Test()"); } } class Program { static void Main(string[] args) { A a = new A(); B b = new B(); C c = new C(); a.Test(); // output --> "A::Test()" b.Test(); // output --> "B::Test()" c.Test(); // output --> "C::Test()" a = new B(); a.Test(); // output --> "A::Test()" b = new C(); b.Test(); // output --> "C::Test()" Console.ReadKey(); } } }
ZŁOTE SŁOWA: słowo kluczowe virtual służy do modyfikowania metody, właściwości, indeksatora lub zdarzenia zadeklarowanego w klasie bazowej i umożliwia zastąpienie ich w klasie pochodnej.
Słowo kluczowe override służy do rozszerzania lub modyfikowania metody wirtualnej / abstrakcyjnej, właściwości, indeksatora lub zdarzenia klasy bazowej do klasy pochodnej.
Słowo kluczowe new służy do ukrywania metody, właściwości, indeksatora lub zdarzenia klasy bazowej w klasie pochodnej.
CIESZYĆ SIĘ :-)
źródło
Ten link zapewni lepsze zrozumienie dzięki bardzo prostemu przykładowi https://stackoverflow.com/a/2392656/3373865
źródło