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 修飾子を使用しているプロパティ宣言をインクルードします。
使用例
この例ではShape のクラスに 2 本の座標 xy と Area() の仮想メソッドがあります。図形のクラス、たとえば Circle、Cylinder、および Sphere が Shape クラスを継承し、各図形について、表面積が計算されます。各派生クラスには、Area() の独自のオーバーライド実装があります。
次の宣言に示すように継承クラス CircleSphere と Cylinder 基本クラスを初期化するすべてのコンストラクターを使用してください。
public Cylinder(double r, double h): base(r, h) {}
次のプログラムはメソッドに関連付けられたオブジェクトへ Area() ためのメソッドの適切な実装を呼び出すことによって各図形の適切な領域を計算して表示します。
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# 言語仕様」を参照してください。言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。