virtual (Referencia de C#)

La palabra clave virtual se usa para modificar una declaración de método, propiedad, indizador o evento y permitir que se invalide en una clase derivada. Por ejemplo, cualquier clase que herede este método puede reemplazarlo:

public virtual double Area()
{
    return x * y;
}

Un miembro de reemplazo de una clase derivada puede modificar la implementación de un miembro virtual. Para obtener más información sobre cómo usar la palabra clave virtual, vea Control de versiones con las palabras clave Override y New y Saber cuándo usar las palabras clave Override y New (Guía de programación de C#).

Observaciones

Cuando se invoca a un método virtual, se busca un miembro de reemplazo en el tipo en tiempo de ejecución del objeto. Se llama al miembro de reemplazo en la clase más derivada, que podría ser el miembro original si ninguna clase derivada ha invalidado al miembro.

De forma predeterminada, los métodos son no virtuales. No se puede invalidar un método no virtual.

El modificador virtual no se puede usar con los modificadores static, abstract, private o override. En el siguiente ejemplo 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 (!string.IsNullOrEmpty(value))
            {
                _name = value;
            }
            else
            {
                _name = "Unknown";
            }
        }
    }
}

Las propiedades virtuales se comportan como métodos virtuales, salvo por las diferencias en la sintaxis de declaración e invocación.

  • Es un error usar el modificador virtual en una propiedad estática.

  • Una propiedad virtual heredada se puede invalidar en una clase derivada al incluir una declaración de propiedad que use el modificador override.

Ejemplo

En este ejemplo, la clase Shape contiene las dos coordenadas x, y y el método virtual Area(). Las distintas clases de formas como Circle, Cylinder y Sphere heredan la clase Shape y se calcula el área de cada figura. Cada clase derivada tiene su propia implementación de invalidación de Area().

Observe que las clases heredadas Circle, Sphere y Cylinder usan constructores que inicializan la clase base, como se muestra en la siguiente declaración.

public Cylinder(double r, double h): base(r, h) {}

El programa siguiente calcula y muestra el área apropiada de cada figura al invocar a la implementación adecuada del método Area(), según el objeto asociado al método.

class TestClass
{
    public class Shape
    {
        public const double PI = Math.PI;
        protected double _x, _y;

        public Shape()
        {
        }

        public Shape(double x, double y)
        {
            _x = x;
            _y = y;
        }

        public virtual double Area()
        {
            return _x * _y;
        }
    }

    public class Circle : Shape
    {
        public Circle(double r) : base(r, 0)
        {
        }

        public override double Area()
        {
            return PI * _x * _x;
        }
    }

    public class Sphere : Shape
    {
        public Sphere(double r) : base(r, 0)
        {
        }

        public override double Area()
        {
            return 4 * PI * _x * _x;
        }
    }

    public class Cylinder : Shape
    {
        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;
        Shape c = new Circle(r);
        Shape s = new Sphere(r);
        Shape 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, consulte 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