virtual (Referencia de C#)
La palabra clave virtual se utiliza para modificar un método, propiedad, indizador o declaración de evento y permite invalidar cualquiera de estos elementos en una clase derivada. En el siguiente ejemplo, cualquier clase que hereda este método puede reemplazarlo:
public virtual double Area()
{
return x * y;
}
La implementación de un miembro virtual puede reemplazarse por un miembro de reemplazo de una clase derivada. Para obtener más información sobre cómo utilizar la palabra clave virtual, vea Control de versiones con las palabras clave Override y New (Guía de programación de C#) y Saber cuándo utilizar las palabras clave Override y New (Guía de programación de C#).
Comentarios
Cuando se invoca un método virtual, el tipo en tiempo de ejecución del objeto se comprueba para ver si existe un miembro de reemplazo. Se realiza una llamada al miembro de reemplazo que está en la clase de mayor derivación, el cual puede ser el miembro original, si no existe ninguna clase derivada que haya reemplazado el miembro.
De forma predeterminada, los métodos son no virtuales. No se puede reemplazar un método no virtual.
No puede utilizar el modificador virtual con los modificadores static, abstract, private u override. En el ejemplo siguiente, se muestra una propiedad virtual:
class MyBaseClass
{
// virtual auto-implemented property. Overrides can only
// provide specialized behavior if they implement get and set accessors.
public virtual string Name { get; set; }
// ordinary virtual property with backing field
private int num;
public virtual int Number
{
get { return num; }
set { num = value; }
}
}
class MyDerivedClass : MyBaseClass
{
private string name;
// Override auto-implemented property with ordinary property
// to provide specialized accessor behavior.
public override string Name
{
get
{
return name;
}
set
{
if (value != String.Empty)
{
name = value;
}
else
{
name = "Unknown";
}
}
}
}
Las propiedades virtuales funcionan como los métodos abstractos, salvo en lo que se refiere a las diferencias en la sintaxis de las declaraciones e invocaciones.
Es incorrecto utilizar el modificador virtual para una propiedad estática.
Una propiedad virtual heredada se puede reemplazar en una clase derivada si se incluye una declaración de propiedad que use el modificador override.
Ejemplo
En este ejemplo, la clase Dimensions contiene las dos coordenadas x e y y el método virtual Area(). Las clases de las diferentes figuras, como Circle, Cylinder y Sphere, heredan la clase Dimensions, que permite calcular el área de la superficie de cada figura. Cada clase derivada dispone de su propia implementación de Area() (método de reemplazo). El programa calcula y muestra el área apropiada para cada figura invocando la implementación adecuada del método Area() según el objeto asociado al método.
Observe que todas las clases heredadas Circle, Sphere y Cylinder utilizan constructores que inicializan la clase base, por ejemplo:
public Cylinder(double r, double h): base(r, h) {}
Esto es similar a la lista de inicializaciones de C++.
class TestClass
{
public class Dimensions
{
public const double PI = Math.PI;
protected double x, y;
public Dimensions()
{
}
public Dimensions(double x, double y)
{
this.x = x;
this.y = y;
}
public virtual double Area()
{
return x * y;
}
}
public class Circle : Dimensions
{
public Circle(double r) : base(r, 0)
{
}
public override double Area()
{
return PI * x * x;
}
}
class Sphere : Dimensions
{
public Sphere(double r) : base(r, 0)
{
}
public override double Area()
{
return 4 * PI * x * x;
}
}
class Cylinder : Dimensions
{
public Cylinder(double r, double h) : base(r, h)
{
}
public override double Area()
{
return 2 * PI * x * x + 2 * PI * x * y;
}
}
static void Main()
{
double r = 3.0, h = 5.0;
Dimensions c = new Circle(r);
Dimensions s = new Sphere(r);
Dimensions l = new Cylinder(r, h);
// Display results:
Console.WriteLine("Area of Circle = {0:F2}", c.Area());
Console.WriteLine("Area of Sphere = {0:F2}", s.Area());
Console.WriteLine("Area of Cylinder = {0:F2}", l.Area());
}
}
/*
Output:
Area of Circle = 28.27
Area of Sphere = 113.10
Area of Cylinder = 150.80
*/
Especificación del lenguaje C#
Para obtener más información, vea la Especificación del lenguaje C#. La especificación del lenguaje es la fuente definitiva de la sintaxis y el uso de C#.
Vea también
Referencia
Modificadores (Referencia de C#)
Polimorfismo (Guía de programación de C#)