クラス (Visual C# Express)

更新 : 2007 年 11 月

オブジェクト指向プログラミング言語である C# では、他の最新の言語と同様、関連するフィールド、メソッド、プロパティ、およびイベントをクラスと呼ばれるデータ構造体にグループ化します。

クラスとオブジェクト

簡単に言えば、クラスはカスタム データ型の設計図の働きをします。クラスを定義したら、メモリに読み込んで使用します。メモリに読み込まれたクラスは、オブジェクトまたはインスタンスと呼ばれます。クラスのインスタンスは、C# のキーワード new を使用して作成します。

SampleClass というクラス定義の例を次に紹介し、このクラスのインスタンスである sampleClass1 というオブジェクトの作成方法を示します。C# ではクラス内で Main 関数を定義する必要があるため、次のコードでは Program クラスも定義しますが、このクラスはオブジェクトの作成には使用されません。

using System;

class SampleClass
{
    public void SayHello()
    {
        Console.WriteLine("Hello, World!");
    }
}

class Program
{
    //Main is the entrypoint, where every C# program starts
    static void Main(string[] args)
    {
        SampleClass sampleClass1 = new SampleClass();  // Create an object
        sampleClass1.SayHello();                       // Call a method
    }
}

同じ設計図を基に何軒でも家を建てることができるのと同様に、同じクラスのオブジェクトはいくつでもインスタンス化できます。同じクラスの多数のオブジェクトを格納する配列やリストが使用されることはよくあります。クラスの各インスタンスは別個のメモリ空間を使用し、そのフィールドの値は個々に独立しています (後述の静的フィールドを除く)。次のコード例では、Animal 型のオブジェクトを 2 つ作成し、1 つはサイズを 2 に、もう 1 つはサイズを 3 に設定します。ただし、この規則には静的メンバという重要な例外が存在します。

静的メンバとインスタンス メンバ

静的メンバとは、クラスの特定のインスタンスを参照せずにアクセスできるメソッドやフィールドのことです。最もよく使用される静的メソッドは、すべての C# プログラムのエントリ ポイントである Main です。Main メソッドを呼び出すために、このメソッドを格納するクラスのインスタンスを作成する必要はありません。他によく使用される静的メソッドとしては、Console クラスの WriteLine があります。静的メソッドにアクセスする際は構文の違いに注意が必要です。インスタンス名ではなく、Console.WriteLine のドット演算子の左側にあるクラス名を使用します。

クラス フィールドを static として宣言した場合、そのクラスのすべてのインスタンスがそのフィールドを "共有" することになります。次のコード例の size が static として宣言されており、1 つの Animal オブジェクトで値が変更された場合、Animal 型のすべてのオブジェクトでも値が変更されます。

静的クラスとは、そのすべてのメンバが静的であるクラスのことです。静的クラス、静的メソッド、および静的フィールドは、高いパフォーマンスや効率性が求められる特定のシナリオでは有用です。ただし、実際には静的フィールドであるのにインスタンス フィールドであると見なしてしまった場合、軽度のエラーが発生することがあります。詳細については、「静的クラスと静的クラス メンバ (C# プログラミング ガイド)」を参照してください。

クラスとファイル

C# プログラムには、必ず 1 つ以上のクラスがあります。プログラミング手法として優れたものにするには、プログラムを設計するときに、各ソース コード (.cs) ファイルに 1 つのクラスを維持するようにします。ただし、これは必要条件ではありません。C# 統合開発環境 (IDE) を使用してクラスを作成すると、同時に新しいソース コード ファイルが自動的に作成されます。

カプセル化

通常、クラスは、ある "もの" の特性およびそれが実行するアクションを表します。たとえば、ある動物を C# クラスとして表すには、そのサイズ、速度、および強さを数値として指定すると共に、MoveLeft()、MoveRight()、SpeedUp()、Stop() などの関数を指定する必要があります。これらの関数では、"動物" にこのようなアクションを実行させるためのコードを記述します。C# では、この動物クラスは次のようになります。

    public class Animal
    {
        private int size;
        private float speed;
        private int strength;

        public void MoveLeft()  // method
        {
            // code goes here...
        }

        // other methods go here...
    }

「.NET Framework Class Library」に目を通すと、各クラスが XmlDocumentStringForm などの "もの" を表し、それぞれの "もの" には、実行可能なさまざまなアクション (メソッド)、読み取ったり変更したりできる特性 (プロパティ)、および特定のアクションを実行する際に送出する通知 (イベント) が備わっていることがわかります。メソッド、プロパティ、イベント、および他のすべての内部変数や内部定数 (フィールド) を、クラスのメンバといいます。

メンバをクラスにグループ化することは論理的な手法であるだけでなく、これによって、他のコードからのアクセスを避ける必要があるデータや関数を、隠すこともできます。この原理をカプセル化といいます。.NET Framework クラス ライブラリに目をとおしても、確認できるのはクラスのパブリック メンバだけです。各クラスには、そのクラスや関連クラスが内部的に使用するプライベート メンバも含まれている可能性がありますが、プライベート メンバはアプリケーションによる使用を意図したものではありません。独自のクラスを作成したら、パブリックにするメンバとプライベートにするメンバを決める必要があります。

継承

クラスは別のクラスを継承できます。つまり、継承されたクラスには元のクラスのすべてのパブリック メンバとプライベート メンバが含まれるだけでなく、追加のメンバを独自に定義して含めることもできます。元のクラスを基本クラス、新しいクラスを派生クラスと呼びます。派生クラスを作成する目的は、基本クラスをより特化したクラスを表すことにあります。たとえば、Animal を継承する Cat クラスを定義できます。Cat は Animal にできるすべてのアクションを実行できるだけでなく、それ以外にも固有のアクションを 1 つ実行できます。C# コードは次のようになります。

    public class Cat : Animal
    {
        public void Purr()
        {
        }
    }

Cat : Animal という表記は、Cat が Animal を継承したものであり、したがって Cat も MoveLeft メソッドと size、speed、および strength という 3 つのプライベート変数を備えていることを示しています。Cat を継承する SiameseCat クラスを定義した場合、このクラスには Cat のすべてのメンバと Animal のすべてのメンバが含まれることになります。

ポリモーフィズム

コンピュータ プログラミングの分野におけるポリモーフィズムとは、基本クラスから継承したメソッドを派生クラスで再定義、つまりオーバーライドできることを指します。基本クラスのメソッドで定義されているのとは別の内容、または基本クラスのメソッドでは未定義の特定の内容を実行する必要がある場合にオーバーライドを行います。たとえば、Animal.MoveLeft メソッドは、すべての動物に当てはまるように非常に一般的なものでなければならないため、"動物の頭が X の方向を指すように向きを変更する" などのように、きわめて単純な内容になっています。ところが Cat クラスの場合、これでは不十分な場合があります。Cat が向きを変える際に、前足と尾をどのように動かすかを指定する必要が生じることがあるためです。また、Fish クラスや Bird クラスを定義した場合、おそらくクラスごとに異なった方法で MoveLeft メソッドをオーバーライドする必要が生じます。特定のクラスについて MoveLeft メソッドの動作をカスタマイズできるため、クラスを作成しそのメンバを呼び出すコードで、地球上に存在する動物ごとに個別のメソッドを指定する必要はありません。オブジェクトが Amimal を継承している限り、呼び出し元のコードで MoveLeft メソッドを呼び出すだけで、そのオブジェクトの独自バージョンのメソッドを呼び出すことができます。

コンストラクタ

すべてのクラスにコンストラクタがあります。コンストラクタは、クラスと同じ名前を共有するメソッドです。コンストラクタは、クラス定義に基づいてオブジェクトを作成する際に呼び出されます。通常、コンストラクタはクラスで定義されている、変数の初期値を設定します。初期値が、ゼロ (数値データ型)、false (ブール型)、または null (参照型) の場合、初期値の設定は必要ありません。これらのデータ型は自動的に初期化されるためです。

コンストラクタは、任意の数のパラメータを使用して定義できます。パラメータを持たないコンストラクタを既定のコンストラクタといいます。次の例では、既定のコンストラクタと、文字列を受け取るコンストラクタを持つクラスを定義し、それぞれを使用します。

class SampleClass
{
    string greeting;

    public SampleClass()
    {
        greeting = "Hello, World";
    }

    public SampleClass(string message)
    {
        greeting = message;
    }

    public void SayHello()
    {
        System.Console.WriteLine(greeting);
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Use default constructor.
        SampleClass sampleClass1 = new SampleClass();
        sampleClass1.SayHello();

        // Use constructor that takes a string parameter.
        SampleClass sampleClass2 = new SampleClass("Hello, Mars");
        sampleClass2.SayHello();
    }
}

演算子のオーバーロード

同じ名前 (上記の例では SampleClass()) を持つ別のメソッドを作成することを、"オーバーロード" といいます。引数のリストが存在する場合、オブジェクトが作成されるたびにこのリストが提供されるため、コンパイラは使用するメソッドを識別できます。オーバーロードにより、コードの柔軟性とわかりやすさが向上します。

デストラクタ

デストラクタは、C++ の使用経験のあるユーザーには既になじみのあるものです。C# には自動ガベージ コレクション システムが備わっているため、クラスでアンマネージ リソースを使用する場合を除き、デストラクタの実装が必要になることはまずありません。詳細については、「デストラクタ (C# プログラミング ガイド)」を参照してください。

構造体

構造体は型の一種で、継承をサポートしないことを除き多くの点でクラスに似ています。詳細については、「構造体 (Visual C# Express)」を参照してください。

参照

処理手順

方法 : オブジェクトでメソッドを呼び出す (Visual C#)

方法 : クラスから継承する (Visual C#)

概念

C# 言語の概要

参照

クラスと構造体 (C# プログラミング ガイド)

class (C# リファレンス)

struct (C# リファレンス)