¿Por qué declararía un método como "virtual"?
¿Cuál es el beneficio de usar virtual?
El Modificador virtual se usa para marcar que un método \ propiedad (ect) se puede modificar en una clase derivada usando el modificador de anulación .
Ejemplo:
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()
}
Virtual permite que una clase heredada reemplace un método que luego usa la clase base.
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();
}
}
Cuando ejecute el programa, su salida será:
Zing
A Thingy in Action.
Wiggy
A Thingy in Action.
Observe cómo, aunque Widget llamó al método Action () definido en el nivel Thingy, internamente Thingy llamó al método StepA () de Widget.
La respuesta básica es que da a los herederos de una clase más flexibilidad. Por supuesto, tienes que diseñar bien tu clase o podría causar estragos.
Un método virtual es un tipo de método en el que las llamadas al método reales dependen del tipo de tiempo de ejecución del objeto subyacente.
Un método no virtual es un tipo de método en el que el método real llamado depende del tipo de referencia del objeto en el punto de invocación del método.
Métodos virtuales en MSDN
fuente
Incluso si no planea derivar de la clase, marcar el método como virtual puede ser necesario para burlarse de la clase. Algunos marcos de burla solo le permiten burlarse de métodos virtuales. Tenga en cuenta que los métodos que implementan una interfaz son virtuales implícitamente.
Utilizo RhinoMocks que tiene esta restricción y he decidido marcar mis métodos como virtuales de forma predeterminada solo por esta razón. Para mí, esta es probablemente la razón más importante para utilizar métodos virtuales, ya que los casos en los que entra en juego la herencia son mucho menos frecuentes.
fuente
Los métodos virtuales son similares a los métodos abstractos en clases base, excepto que su implementación en clases derivadas es opcional. También puede poner lógica en el método virtual y anularlos en clases derivadas.
fuente
¡Una breve pregunta, una breve respuesta! Califique su método como "virtual" si cree que heredará de la clase a la que pertenece.
Una respuesta más larga: "virtual le permite anular, para dar otro significado a su método en una clase derivada.
fuente
Para poder anularlo en clases heredadas.
Consulte la entrada de MSDN para la palabra clave. Eso lo explica más a fondo.
fuente
No hace falta decir que los métodos virtuales son útiles cuando su código intenta cumplir con el principio abierto cerrado
Lea más sobre el principio abierto cerrado aquí , el documento técnico original de OCP del tío Bob.
Además, tenga en cuenta que los métodos no son virtuales de forma predeterminada en C # a diferencia de Java.
fuente
Aquí se explica claramente con un ejemplo de método virtual C #
fuente
Las funciones virtuales son las funciones que realmente no existen. La clase derivada puede modificar la función virtual anulándola. Las funciones virtuales son una de las formas de lograr el polimorfismo en tiempo de ejecución.
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(); } }
fuente
public
modificadores de acceso despuésclass A
yclass B
provocan errores en tiempo de compilación. La accesibilidad de los miembros en la clase base de la clase derivada se especifica de forma individual desde la clase base (por defecto, los miembros lo sonprivate
).El tiempo de ejecución tiene lugar durante el tiempo de compilación.
Cuando declara un método como virtual, declararlo en la clase derivada requiere que agregue un modificador
override
onew
.podemos ver eso cuando
TrySpeak
. Al pasar hijo y padre, ambos llaman a Hablar de padre, mientrasTryScream
que llamarían a cada método.Para entender esto, hay algunas cosas que debemos saber, en una instancia de Child. Hay dos
Scream
métodos de la clase Child o la clase Father. Podríamos llamar alScream
clase para niños o para padres. Debido a queVirtaul
Modifier marca el método para que pueda ser reemplazado por la clase derivada, lo que significa que inclusoScream
se llama desde la clase Father, se reemplaza, sería diferente si usa un nuevo modificador.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(); } }
fuente
En C #, para anular el método de la clase base en la clase derivada, debe declarar el método de la clase base como virtual y el método de la clase derivada como anulado como se muestra a continuación:
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(); } } }
También puede combinar la ocultación de métodos y la anulación de métodos utilizando la palabra clave virtual y nueva, ya que el método de una clase derivada puede ser virtual y nuevo al mismo tiempo. Esto es necesario cuando desea anular aún más el método de clase derivada en el siguiente nivel, ya que estoy anulando la Clase B, el método Test () en la Clase C, como se muestra a continuación:
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(); } } }
PALABRAS DE ORO: La palabra clave virtual se utiliza para modificar un método, propiedad, indexador o evento declarado en la clase base y permitir que se anule en la clase derivada.
La palabra clave override se usa para extender o modificar un método, propiedad, indexador o evento virtual / abstracto de la clase base en una clase derivada.
La nueva palabra clave se utiliza para ocultar un método, propiedad, indexador o evento de la clase base en la clase derivada.
DISFRUTA :-)
fuente
Este enlace le proporcionará una mejor comprensión con un ejemplo muy sencillo https://stackoverflow.com/a/2392656/3373865
fuente