virtual(C# 参考)virtual (C# Reference)

virtual 关键字用于修改方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。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. 例如,此方法可被任何继承它的类替代:For example, this method can be overridden by any class that inherits it:

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

虚拟成员的实现可由派生类中的替代成员更改。The implementation of a virtual member can be changed by an overriding member in a derived class. 有关如何使用 virtual 关键字的详细信息,请参阅使用 Override 和 New 关键字进行版本控制了解何时使用 Override 和 New 关键字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.

备注Remarks

调用虚拟方法时,将为替代的成员检查该对象的运行时类型。When a virtual method is invoked, the run-time type of the object is checked for an overriding member. 将调用大部分派生类中的该替代成员,如果没有派生类替代该成员,则它可能是原始成员。The overriding member in the most derived class is called, which might be the original member, if no derived class has overridden the member.

默认情况下,方法是非虚拟的。By default, methods are non-virtual. 不能替代非虚方法。You cannot override a non-virtual method.

virtual 修饰符不能与 staticabstract``privateoverride 修饰符一起使用。You cannot use the virtual modifier with the static, abstract, private, or override modifiers. 以下示例显示了虚拟属性: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";
            }
        }
    } 
}

除声明和调用语法不同外,虚拟属性的行为与虚拟方法相似。Virtual properties behave like virtual methods, except for the differences in declaration and invocation syntax.

  • 在静态属性上使用 virtual 修饰符是错误的。It is an error to use the virtual modifier on a static property.

  • 通过包括使用 override 修饰符的属性声明,可在派生类中替代虚拟继承属性。A virtual inherited property can be overridden in a derived class by including a property declaration that uses the override modifier.

示例Example

在该示例中,Shape 类包含 xy 两个坐标和 Area() 虚拟方法。In this example, the Shape class contains the two coordinates x, y, and the Area() virtual method. 不同的形状类(如 CircleCylinderSphere)继承 Shape 类,并为每个图形计算表面积。Different shape classes such as Circle, Cylinder, and Sphere inherit the Shape class, and the surface area is calculated for each figure. 每个派生类都有各自的 Area() 替代实现。Each derived class has its own override implementation of Area().

请注意,继承的类 Circle``SphereCylinder 均使用初始化基类的构造函数,如下面的声明中所示。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) {}

根据与方法关联的对象,下面的程序通过调用 Area() 方法的相应实现来计算并显示每个对象的相应区域。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
*/

C# 语言规范C# language specification

有关详细信息,请参阅 C# 语言规范For more information, see the C# Language Specification. 该语言规范是 C# 语法和用法的权威资料。The language specification is the definitive source for C# syntax and usage.

请参阅See also