プログラミングを試してみたい人向けのC#プログラミングチュートリアル

Dictionaryの使い方

POINT
  • インターフェースとは何か
  • インターフェースを実装する方法
  • インターフェースをどう使うか
目次

インターフェースとは

インターフェースは直訳すると「接点」です。繋ぎ目を表します。
プログラムでのインターフェースはクラス間での取り決めのような意味があります。
このインターフェースが実装(クラスに適用)されている場合、こんなメソッドが実装されていますという約束になります。

下記のように定義します。

使用例
public interface インターフェース名
{
    メソッド定義;
}

クラスにインターフェースを実装するには、クラス名の後ろに:を付けて、その後ろにインターフェース名を記載します。
インターフェースで定義されたメソッドがない場合、コンパイルエラーになります。

使用例
public calass クラス名 : インタフェース名
{
    メソッド定義
    {
        メソッドの中身
    }
}

下記が具体例です。

サンプルプログラム
// 乗り物インターフェース
public interface IVehicle
{
    // 名前を返すメソッドを持つことを定義
    string Name();
}

// 自転車クラス
public class Bicycle : IVehicle
{
    // インタフェースで定義されたメソッド
    public string Name()
    {
        return "自転車";
    }
}

インターフェースにできること

インターフェースを使うことで、同じインターフェースを持つクラスであれば区別せずに扱うことができるようになります。
次の例ではRiderクラスはBicycleクラスやCarクラスのことを知りません。
それでも、インターフェースとして扱うことでBicycleクラスやCarクラスの処理を呼び出せるようになっています。
次のファイルを同じフォルダ内に作成してください。

ファイル名:Program.cs
using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        Rider rider = new Rider();
        
        rider.Ride(new Bicycle());
        rider.Ride(new Car());
        
        // キー入力待ち
        Console.ReadKey();
    }
}

// 乗り物インターフェース
public interface IVehicle
{
    // 名前を返すメソッドを持つことを定義
    string Name();
}

// 自転車クラス
public class Bicycle : IVehicle
{
    public string Name()
    {
        return "自転車";
    }
}

// 車クラス
public class Car : IVehicle
{
    public string Name()
    {
        return "車";
    }
}

// 乗り手
public class Rider
{
    // Riderクラスはインターフェースさえわかれば、クラスの中身は意識しない
    public void Ride(IVehicle vehicle)
    {
        Console.WriteLine(vehicle.Name() + "に乗りました。");
    }
}
ファイル名:Compile.bat
C:¥Windows¥Microsoft.NET¥Framework¥v4.0.30319¥csc.exe *.cs
pause

ファイルを作成できたらCompile.batを実行してみましょう。
同じフォルダにProgram.exeが作成されます。
Program.exeを実行して「Program.exe 実行結果」のように表示されたら成功です。

Program.exe 実行結果
自転車に乗りました。
車に乗りました。

インターフェースは複数実装できる

前述の例の場合、継承でも近いことができます。
ただ継承の場合は、一つのクラスに継承元は一つだけの制限があります。
インターフェースの場合は一つのクラスに複数実装することができるというメリットがあります。

インタフェース名をカンマ区切りで並べて記載することで複数のインタフェースを実装できます。

使用例
public class Stroller : IVehicle, IForBabies
{
 ・・・

Strollerはベビーカーのことなのですが、乗り物でかつベビー用品という実装になります。

インターフェースを使ってクラスを疎結合にできる

もう一つインターフェースを使うメリットはクラス同士を疎結合にできることです。
相互に処理を呼び出したい場合、クラスが密結合になってしまう問題が生じます。
インターフェースを介すことで、疎結合にすることができます。

次の例だと、ITestClassListnerを確認することでTestClassを使うにはPrintMessage()メソッドを用意する必要があることがすぐにわかります。
他のクラスでTestClassを使いたい場合、ITestClassListnerを実装して、PrintMessage()メソッドを用意すれば使うことが可能になります。
この例ではPrintMessage()メソッドだけの関連ですが、複数のメソッドが絡んでくるとインターフェースがないと2つのクラスは後からでは切り離すことができなくなってしまいます。

この結果、俗に言うスパゲッティコード(処理が複雑に入り組んでわかりにくいコード)が生まれます。
インターフェースは、スパゲッティコードを回避するのに役に立つ仕組みです。

ファイル名:Program.cs
using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        // メイン処理呼出し
        (new TestClient()).Main();
        // キー入力待ち
        Console.ReadKey();
    }
}

// interfaceクラス 
public interface ITestClassListner
{
    void PrintMessage();
}

// TestClassの使用者となるクラス、ITestClassListnerを実装
public class TestClient : ITestClassListner
{
    // interfaceのPrintMessageメソッド実装
    public void PrintMessage()
    {
        Console.WriteLine("TestClient.PrintMessage!");
    }
    
    public void Main()
    {
        // newの際に自クラスを渡す
        TestClass testClass = new TestClass(this);
        // TestClassの処理呼出し
        testClass.Execute();
    }
}

// TestClientから呼び出されるクラス
public class TestClass
{
    private ITestClassListner _listener;

    public TestClass(ITestClassListner listener)
    {
        // 生成時に渡されたinterfaceクラス保持
        _listener = listener;
    }

    public void Execute()
    {
        Console.WriteLine("TestClass.Execute.Begin!");
        // 一部だけ呼出し元の処理を呼び出す
        this._listener.PrintMessage();
        Console.WriteLine("TestClass.Execute.End!");
    }
}

前述と同じように同フォルダにCompile.batも用意して実行、Program.exeを実行してみてください。
「Program.exe 実行結果」のように表示されます。

Program.exe 実行結果
TestClass.Execute.Begin!
TestClient.PrintMessage!
TestClass.Execute.End!