virtual (C# リファレンス)
virtual
キーワードは、メソッド、プロパティ、インデクサー、またはイベント宣言を変更し、それを派生クラスでオーバーライドできるようにするために使用されます。 たとえば、次のメソッドはそれを継承する任意のクラスでオーバーライドできます。
public virtual double Area()
{
return x * y;
}
仮想メンバーの実装は、派生クラスのオーバーライド メンバーによって変更できます。 virtual
キーワードの使い方について詳しくは、「Override キーワードと New キーワードによるバージョン管理」および「Override キーワードと New キーワードを使用する場合について」をご覧ください。
注釈
仮想メソッドが呼び出されると、オブジェクトの実行時の型が、オーバーライドするメンバーに対してチェックされます。 いずれの派生クラスもメンバーをオーバーライドしなかった場合は、最派生クラスのオーバーライド メンバー (元のメンバーである可能性があります) が呼び出されます。
既定では、メソッドは仮想ではありません。 非仮想メソッドをオーバーライドすることはできません。
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 (!string.IsNullOrEmpty(value))
{
_name = value;
}
else
{
_name = "Unknown";
}
}
}
}
仮想プロパティは、宣言と呼び出しの構文の違いを除けば、仮想メソッドと似た働きを持ちます。
virtual
修飾子を静的プロパティに対して使うのは誤りです。継承する仮想プロパティは、派生クラス内で
override
修飾子を使ったプロパティ宣言を記述することでオーバーライドすることができます。
例
この例では、Shape
クラスに 2 つの座標 (x
と y
) と仮想メソッド Area()
が含まれています。 他の図形クラス (Circle
、 Cylinder
、Sphere
など) は Shape
クラスを継承しており、各図の表面積が計算されています。 各派生クラスは、Area()
のオーバーライド実装を独自に持っています。
次の宣言に示すように、継承されたクラス (Circle
、 Cylinder
、および Sphere
) はいずれも、基底クラスを初期化するコンス トラクターを使用します。
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)
{
_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# 言語仕様
詳細については、「C# 言語の仕様」を参照してください。 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。
関連項目
.NET