virtual (C#-Referenz)

Das Schlüsselwort virtual wird zum Ändern einer Methoden-, Eigenschaften-, Indexer- oder Ereignisdeklaration verwendet, und lässt zu, dass sie in einer abgeleiteten Klasse außer Kraft gesetzt werden. Diese Methode kann z.B. von jeder Klasse, die sie erbt, überschrieben werden:

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

Die Implementierung eines virtuellen Members kann durch einen overriding member (überschreibenden Member) in einer abgeleiteten Klasse geändert werden. Weitere Informationen zur Verwendung des virtual-Schlüsselworts finden Sie unter Versionsverwaltung mit den Schlüsselwörtern „override“ und „new“ und Wann müssen die Schlüsselwörter „override“ und „new“ verwendet werden?.

Bemerkungen

Wenn eine virtuelle Methode aufgerufen wird, wird der Laufzeittyp des Objekts auf einen überschreibenden Member überprüft. Der überschreibende Member in der abgeleitetsten Klasse (bei dem es sich um den ursprünglichen Member handeln könnte) wird aufgerufen, wenn keine abgeleitete Klasse den Member außer Kraft gesetzt hat.

Standardmäßig sind Methoden nicht virtuell. Sie können keine nicht virtuelle Methode überschreiben.

Sie können den Modifizierer virtual nicht mit den Modifizierern static, abstract, private oder override verwenden. Im folgenden Beispiel wird eine virtuelle Methode gezeigt:

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";
            }
        }
    }
}

Virtuelle Eigenschaften verhalten sich wie virtuelle Methoden – sie unterscheiden sich lediglich in der Deklarations- und Aufrufsyntax.

  • Es ist ein unzulässig, den virtual-Modifizierer für eine statische Eigenschaft zu verwenden.

  • Eine virtuelle vererbte Eigenschaft kann in einer abgeleiteten Klasse mithilfe der Eigenschaftendeklaration, die den Modifizierer override verwendet, außer Kraft gesetzt werden.

Beispiel

In diesem Beispiel enthält die Klasse Shape die zwei Koordinaten x und y und die virtuelle Methode Area(). Andere Formklassen, z.B. Circle, Cylinder und Sphere erben die Klasse Shape. Die Oberfläche wird für jede Abbildung berechnet. Jede abgeleitete Klasse verfügt über ihre eigene Überschreibungsimplementierung von Area().

Beachten Sie, dass die geerbten Klassen Circle, Cylinder und Sphere alle Konstruktoren verwenden, die die Basisklasse initialisieren, wie in der folgenden Deklaration gezeigt.

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

Das folgende Programm berechnet und zeigt den entsprechenden Bereich für jede Abbildung durch Aufruf der entsprechenden Implementierung der Area()-Methode gemäß dem Objekt, das der Methode zugeordnet ist.

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
*/

C#-Sprachspezifikation

Weitere Informationen erhalten Sie unter C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.

Siehe auch