virtual (Referencia de C#)virtual (C# Reference)

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.The virtual keyword is used to modify a method, property, indexer, or event declaration and allow for it to be overridden in a derived class. Por ejemplo, cualquier clase que herede este método puede reemplazarlo:For example, this method can be overridden by any class that inherits it:

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

Un miembro de reemplazo de una clase derivada puede modificar la implementación de un miembro virtual.The implementation of a virtual member can be changed by an overriding member in a derived class. 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#).For more information about how to use the virtual keyword, see Versioning with the Override and New Keywords and Knowing When to Use Override and New Keywords.

ComentariosRemarks

Cuando se invoca a un método virtual, se busca un miembro de reemplazo en el tipo en tiempo de ejecución del objeto.When a virtual method is invoked, the run-time type of the object is checked for an overriding member. 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.The overriding member in the most derived class is called, which might be the original member, if no derived class has overridden the member.

De forma predeterminada, los métodos son no virtuales.By default, methods are non-virtual. No se puede invalidar un método no virtual.You cannot override a non-virtual method.

El modificador virtual no se puede usar con los modificadores static, abstract, private o override.You cannot use the virtual modifier with the static, abstract, private, or override modifiers. En el siguiente ejemplo se muestra una propiedad virtual:The following example shows a virtual property:

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 abstractos, salvo por las diferencias en la sintaxis de declaración e invocación.Virtual properties behave like abstract methods, except for the differences in declaration and invocation syntax.

  • Es un error usar el modificador virtual en una propiedad estática.It is an error to use the virtual modifier on a static property.

  • Una propiedad virtual heredada se puede invalidar en una clase derivada al incluir una declaración de propiedad que use el modificador override.A virtual inherited property can be overridden in a derived class by including a property declaration that uses the override modifier.

EjemploExample

En este ejemplo, la clase Shape contiene las dos coordenadas x, y y el método virtual Area().In this example, the Shape class contains the two coordinates x, y, and the Area() virtual method. Las distintas clases de formas como Circle, Cylinder y Sphere heredan la clase Shape y se calcula el área de cada figura.Different shape classes such as Circle, Cylinder, and Sphere inherit the Shape class, and the surface area is calculated for each figure. Cada clase derivada tiene su propia implementación de invalidación de Area().Each derived class has its own override implementation of 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.Notice that the inherited classes Circle, Sphere, and Cylinder all use constructors that initialize the base class, as shown in the following declaration.

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.The following program calculates and displays the appropriate area for each figure by invoking the appropriate implementation of the Area() method, according to the object that is associated with the method.

class TestClass
{
    public class Shape
    {
        public const double PI = Math.PI;
        protected double x, y;
        
        public Shape()
        {
        }
        
        public Shape(double x, double y)
        {
            this.x = x;
            this.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;
        }
    }

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

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

    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#C# language specification

Para obtener más información, consulte la Especificación del lenguaje C#.For more information, see the C# Language Specification. La especificación del lenguaje es la fuente definitiva de la sintaxis y el uso de C#.The language specification is the definitive source for C# syntax and usage.

Vea tambiénSee also