virtual (C# リファレンス)

virtual キーワードは、メソッド、プロパティ、インデクサー、またはイベントの宣言を修飾し、派生クラスでオーバーライドできるようにするために使用します。 たとえば、このメソッドは、このメソッドを継承するクラスでオーバーライドできます。

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

仮想メンバーの実装は、オーバーライドするメンバーによって派生クラスで変更できます。 virtual キーワードを使用する方法の詳細については、「Override キーワードと New キーワードによるバージョン管理 (C# プログラミング ガイド)」および「Override キーワードと New キーワードを使用する場合について (C# プログラミング ガイド)」を参照してください。

解説

仮想メンバーが呼び出されるときには、オブジェクトの実行時の型が、オーバーライドするメンバーで確認されます。 メンバーをオーバーライドしている派生クラスがない場合には、おそらくはオリジナルのメンバーである、最派生クラスでオーバーライドするメンバーが呼び出されます。

既定では、これらのメソッドは非仮想です。 非仮想メソッドのオーバーライドはできません。

virtual 修飾子は、static、abstract, private、または override の各修飾子と一緒には使用できません。 仮想プロパティの例を次に示します。

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

}

仮想プロパティは抽象メソッドと同様に動作しますが、宣言の構文および呼び出しの構文に相違があります。

  • 静的プロパティで virtual 修飾子を使用するのはエラーです。

  • 継承された仮想プロパティを派生クラス内でオーバーライドできます。オーバーライドするには、override 修飾子を使用しているプロパティ宣言をインクルードします。

使用例

この例では、Dimensions クラスに 2 本の座標軸 x および y と、Area() 仮想メソッドがあります。 図形のクラス、たとえば Circle、Cylinder、および Sphere が Dimensions クラスを継承し、各図形について、表面積が計算されます。 各派生クラスには、Area() の独自のオーバーライド実装があります。 このプログラムは、メソッドと関連付けられているオブジェクトに従って、Area() の適切な実装を呼び出すことによって、各図形の適切な表面積の計算および表示を行います。

継承された Circle、Sphere、および Cylinder のすべてのクラスが、基本クラスを初期化するコンストラクターを使用することに注意してください。たとえば、次のようなコードです。

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

これは、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
    */

C# 言語仕様

詳細については、「C# 言語仕様」を参照してください。 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。

参照

参照

修飾子 (C# リファレンス)

C# のキーワード

ポリモーフィズム (C# プログラミング ガイド)

abstract (C# リファレンス)

override (C# リファレンス)

new (C# リファレンス)

概念

C# プログラミング ガイド

その他の技術情報

C# リファレンス