010. インターフェースとは

過去のブログのアーカイブ
この記事は前身のブログのアーカイブを引き継いだものです. 画像が正しく表示できないなど,コンテンツの表示に問題がある恐れがあります.

プログラミングで、大規模なプログラムを作る際には必ずと言ってもいいほど必要になってくるインターフェース。インターフェースの役割を覚えておきましょう

インターフェースは枠組み

まずクラスとインターフェースの関係性なのですが、クラスとは変数やメソッドの集まりだと紹介しました。
もっと具体的に言いますと、クラスには変数定数メソッド・イベント・デリゲート、そして静的なメンバーも含まれています。
インターフェースも同じなのですが、肝心な点が1つ。インターフェースはメンバーは書かれていても中身は書かれてないのです。
ではサンプルに見てみましょう。

public interface TestInterface
{
    int Value;
    void Test();
}

変数の場合は宣言だけ、メソッドも宣言(戻り値・パラメータを含む)だけを書きます。
また、インターフェースでは、中身のメンバーにアクセス修飾子を指定することはできません。(自動的にpublicが指定されます)
また、インターフェースに含めるメンバーは、変数・メソッド・イベント・プロパティのみです。

インターフェースの役割

では中身を書いていないのになぜこんなのが必要になるかといいますと、インターフェースはメンバーの存在を保証する役割があります。
例えば先ほどのインターフェースを使ったサンプルを見てみましょう。

public class A : TestInterface
{
    public int Value = 100;
    public void Test() {
        Console.WriteLine("Hello World!");
    }
}

まずクラスに実装するインターフェースはクラス名の後に、:(コロン)をつけ、その後ろにインターフェース名を書きます。
このように、インターフェースに書いたメンバーと同じ名前、戻り値、パラメータのものを書く必要があります。また、アクセス修飾子はpublicを指定する必要があります。(その他はダメ)

インターフェースの便利な使い方

では試しにこんなコードを書いてみましょう。先ほどのコードにBクラスが加わっただけです。

public interface TestInterface
{
    int Value;
    void Test();
}
public class A : TestInterface
{
    public int Value = 100;
    public void Test() {
        Console.WriteLine("Hello World!");
    }
}
public class B : TestInterface
{
    public int Value = 200;
    public void Test() {
        Console.WriteLine("こんにちは世界!");
    }
}

TestInterfaceインターフェースとAクラス・Bクラスが定義されました。
そうするとこんなコードが書けちゃうんです。

static void Main()
{
    TestInterface vvv = new A();
    vvv.Test();
    // 出力: Hello World!
}

TestInterfaceという型の変数に、それを実装したクラスを変換なしでつっこめます。
そして、TestInterfaceインターフェースはTestメソッドが実装されているのを保証しているので、vvv変数からTestメソッドが呼び出せます。
では今度はBクラスで実験してみましょう。

static void Main()
{
    TestInterface vvv = new B();
    vvv.Test();
    // 出力: こんにちは世界!
}

同じvvv変数なのにメソッドを呼び出した結果が変わりました。

注意点

あくまで初期化できるのはクラスだけで、インターフェース単体では初期化できません。(中身がないため)

// こんな書き方はできません
TestInterface vvv = new TestInterface();

まとめ

このように、ベースは同じなんだけど肝心なコードが違うという場合にインターフェースを使うと非常に楽にプログラムが組めます。
例えば、RPGのときなんかで、敵にはHPとMP、そして通常攻撃があるとします。敵の種類によってHPやMPが変わってくるので、その辺を各クラスに分けて実装できる。
そして内部ではEnemyインターフェースなんかでまとめて変数で処理してあげると非常に楽にコードが書けるようになります。