¿Por qué declararía un método como "virtual"?
¿Cuál es el beneficio de usar virtual?
¿Por qué declararía un método como "virtual"?
¿Cuál es el beneficio de usar virtual?
Respuestas:
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.
La palabra clave virtual se usa para modificar un método o declaración de propiedad, en cuyo caso el método o la propiedad se denomina miembro virtual. La implementación de un miembro virtual puede ser cambiada por un miembro primordial en una clase derivada.
Cuando se invoca un método virtual, se comprueba el tipo de tiempo de ejecución del objeto para un miembro primordial. Se llama al miembro primordial de la clase más derivada, que podría ser el miembro original, si ninguna clase derivada lo ha reemplazado. (Para obtener más información sobre el tipo de tiempo de ejecución y la implementación más derivada, consulte 10.5.3 Métodos virtuales).
De forma predeterminada, los métodos no son virtuales. No puede anular un método no virtual.
No puede usar el modificador virtual con los siguientes modificadores:
anulación abstracta estática
Las propiedades virtuales se comportan como métodos abstractos, excepto por las diferencias en la sintaxis de declaración e invocación.
- Es un error utilizar el modificador virtual en una propiedad estática.
- Una propiedad virtual heredada se puede anular en una clase derivada al incluir una declaración de propiedad que utilice el modificador de anulación.
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.
¡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.
Para poder anularlo en clases heredadas.
Consulte la entrada de MSDN para la palabra clave. Eso lo explica más a fondo.
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.
Aquí se explica claramente con un ejemplo de método virtual C #
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();
}
}
public
modificadores de acceso después class A
y class 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 son private
).
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
o new
.
podemos ver eso cuando TrySpeak
. Al pasar hijo y padre, ambos llaman a Hablar de padre, mientras TryScream
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 que Virtaul
Modifier marca el método para que pueda ser reemplazado por la clase derivada, lo que significa que incluso Scream
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();
}
}
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 :-)
Este enlace le proporcionará una mejor comprensión con un ejemplo muy sencillo https://stackoverflow.com/a/2392656/3373865