abstract (C# リファレンス)

abstract 修飾子は、その修飾対象の実装が不足しているか、不完全であることを示します。 クラスやメソッド、プロパティ、インデクサー、イベントと組み合わせて abstract 修飾子を使用することができます。 クラス宣言に abstract 修飾子を使用して、クラスは他のクラスの基底クラスとしてのみ使用することを意図し、それ自体ではインスタンス化されないことを示します。 abstract としてマークされたメンバーは、その抽象クラスから派生した非抽象クラスによって実装される必要があります。

例 1

この例で、GetArea の機能は、Shape から派生している Square クラスで実装する必要があります。

abstract class Shape
{
    public abstract int GetArea();
}

class Square : Shape
{
    private int _side;

    public Square(int n) => _side = n;

    // GetArea method is required to avoid a compile-time error.
    public override int GetArea() => _side * _side;

    static void Main()
    {
        var sq = new Square(12);
        Console.WriteLine($"Area of the square = {sq.GetArea()}");
    }
}
// Output: Area of the square = 144

抽象クラスには次の特徴があります。

  • 抽象クラスはインスタンス化できません。

  • 抽象クラスには抽象メソッドとアクセサーを記述することができます。

  • sealed 修飾子を使って抽象クラスを修飾することはできません。2 つの修飾子が逆の意味を持つためです。 sealed 修飾子を指定したクラスは継承が禁止されるのに対し、abstract 修飾子を指定したクラスは継承による使用が強制されます。

  • 抽象クラスから派生した具象クラスには、継承されたすべての抽象メソッドとアクセサーの実際の機能を実装する必要があります。

メソッドまたはプロパティに機能が実装されていないことを示すには、そのメソッドまたはプロパティの宣言で abstract 修飾子を使います。

抽象メソッドには次の特徴があります。

  • 抽象メソッドは、仮想メソッドの性質を暗に含んでいます。

  • 抽象メソッドの宣言は、抽象クラスでしか認められません。

  • 抽象メソッドの宣言には実際の機能が実装されないため、メソッドの本体はありません。つまり、メソッドの宣言は、末尾のセミコロンがあるだけで、シグネチャの後ろに中かっこ ({ }) は存在しません。 次に例を示します。

    public abstract void MyMethod();  
    

    実際の機能は、メソッド (具象クラスのメンバー) に override を指定して実装します。

  • 抽象メソッドの宣言に static 修飾子や virtual 修飾子を使うのは誤りです。

抽象プロパティは、宣言と呼び出しの構文の違いを除けば、抽象メソッドと似た働きを持ちます。

  • abstract 修飾子を静的プロパティに対して使うのは誤りです。

  • 継承する抽象プロパティは、派生クラス内で override 修飾子を使ったプロパティ宣言を記述することでオーバーライドすることができます。

抽象クラスの詳細については、「抽象クラスとシール クラス、およびクラス メンバー」を参照してください。

すべてのインターフェイス メンバーの機能は、抽象クラスで実装する必要があります。

インターフェイスを実装する抽象クラスで、インターフェイス メソッドを抽象メソッドにマップすることもできます。 次に例を示します。

interface I
{
    void M();
}

abstract class C : I
{
    public abstract void M();
}

例 2

この例の DerivedClass クラスは、抽象クラス BaseClass から派生しています。 この抽象クラスには、AbstractMethod という抽象メソッドのほか、XY の 2 つの抽象プロパティが存在します。

// Abstract class
abstract class BaseClass
{
    protected int _x = 100;
    protected int _y = 150;

    // Abstract method
    public abstract void AbstractMethod();

    // Abstract properties
    public abstract int X { get; }
    public abstract int Y { get; }
}

class DerivedClass : BaseClass
{
    public override void AbstractMethod()
    {
        _x++;
        _y++;
    }

    public override int X   // overriding property
    {
        get
        {
            return _x + 10;
        }
    }

    public override int Y   // overriding property
    {
        get
        {
            return _y + 10;
        }
    }

    static void Main()
    {
        var o = new DerivedClass();
        o.AbstractMethod();
        Console.WriteLine($"x = {o.X}, y = {o.Y}");
    }
}
// Output: x = 111, y = 161

この例の抽象クラスを次のようなステートメントでインスタンス化しようとするとどうなるかを次に示します。

BaseClass bc = new BaseClass();   // Error  

このように、抽象クラス 'BaseClass' のインスタンスをコンパイラが作成できないことを伝えるエラーが発生します。

C# 言語仕様

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

関連項目