Dlaczego miałbyś zadeklarować metodę jako „wirtualną”.
Jakie są zalety korzystania z wirtualizacji?
Dlaczego miałbyś zadeklarować metodę jako „wirtualną”.
Jakie są zalety korzystania z wirtualizacji?
Odpowiedzi:
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
Słowo kluczowe virtual służy do modyfikowania metody lub deklaracji właściwości, w którym to przypadku metoda lub właściwość nazywana jest wirtualnym składnikiem. Implementację wirtualnego elementu członkowskiego można zmienić przez zastępujący element członkowski w klasie pochodnej.
Gdy wywoływana jest metoda wirtualna, typ czasu wykonywania obiektu jest sprawdzany pod kątem zastępującego elementu członkowskiego. Wywoływany jest zastępujący element członkowski w klasie najbardziej pochodnej, który może być oryginalnym elementem członkowskim, jeśli żadna klasa pochodna nie przesłania elementu członkowskiego. (Aby uzyskać więcej informacji na temat typu czasu wykonywania i większości pochodnych implementacji, zobacz 10.5.3 Metody wirtualne).
Domyślnie metody nie są wirtualne. Nie można zastąpić metody niewirtualnej.
Nie możesz używać wirtualnego modyfikatora z następującymi modyfikatorami:
statyczne zastąpienie abstrakcyjne
Właściwości wirtualne zachowują się jak metody abstrakcyjne, z wyjątkiem różnic w składni deklaracji i wywołania.
- Użycie modyfikatora wirtualnego na właściwości statycznej jest błędem.
- Dziedziczoną właściwość wirtualną można zastąpić w klasie pochodnej, dołączając deklarację właściwości, która używa modyfikatora override.
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.
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.
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.
Tutaj jest to jasno wyjaśnione na przykładzie metody wirtualnej C #
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();
}
}
public
modyfikatory dostępu Po class A
i class 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
lub new
.
możemy to zobaczyć, kiedy TrySpeak
. Podanie dziecka i ojca, obaj nazywają Mów o ojcu, podczas gdy TryScream
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ć do Scream
klasy Child lub Father. Ponieważ Virtaul
Modifier oznacza metodę, aby mogła być nadpisywana przez klasę pochodną, co oznacza, że nawet ta Scream
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();
}
}
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Ę :-)
Ten link zapewni lepsze zrozumienie dzięki bardzo prostemu przykładowi https://stackoverflow.com/a/2392656/3373865