[C#/Unity]インターフェースについて理解しよう

Unity

Unity/C#でゲームを作っていくと「インターフェース」という言葉を耳にしたことはありませんか?聞いたことはあるが、使い方がよく分からない・・どういう時に使えばいいのかは分からない。
今回はその「分からない」を少しでも分かるようになる、そして使えるようにという目標を掲げて私なりに解説してみます!

インターフェースとは何なのか

インターフェースとは何なのかなのですが、簡単にいうと「指示書」みたいなものです。
例えば、会社で上司は部下に対して「この資料のコピーを取ってきて」とか「出張先のホテルの予約をしといて」とか「明日の会議のパワポーを作っといて」とか、様々な指示があるかと思います。部下は指示通りに実行しないといけません。この一つ一つの指示は関数であり、これらの指示を一つにまとまった指示書はインターフェースそのものです。
イメージとして、指示=関数(メソッド)つまり、関数の宣言を羅列したものがインターフェースになります。

/// <summary>
/// 上司の指示書(インターフェース)
/// ここに上司の指示(関数・メソッド)が書いてあります
/// </summary>
public interface IBossInstruction
{
    // 資料をコピーする
    void CopyTheDocument();

    // ホテルを予約する
    void BookAHotel();

    // パワポーの資料を作る
    void MakePowerPointDocument();
}

インターフェースの特徴

インターフェースは下記の特徴があります。

  • インターフェース内では関数の宣言しかできません(指示だけを書いてある)
  • インターフェースを継承したクラスはその関数のすべてを実装しないといけません(指示されたことをすべて必ず遂行する必要があります)

なぜインターフェースが必要なのか

インターフェースとは何か及び、その特徴を簡単に説明しました。では、どうしてインターフェースが必要なのか、どういう時に使うのかをもうちょっと分かりやすい例で見てみましょう。

例えば「車」を作ることを考えてみましょう。日本の名だたる車の会社と言えばトヨタ、日産(フランス資本)、ホンダ、マツダなどなど沢山あります。それぞれの会社ではそれぞれの特色があります。トヨタならハイブリッドに長けていて、日産は電気自動車、ホンダは走行性能がいいと言われ、マツダはクリーンディーゼルと、車を作ると言っても会社が違えば力の入れる分野も違いますし、出来上がった車の性能やインテリア、エクステリアもそれぞれ違いますよね。
こういった違いはそれぞれの会社が他との差別化のために独自に発展して作るものと言っていいでしょう。逆に独自に発展するものではなく車作りをする上で無くてはならないものは何でしょうか?
もっとも分かりやすいのはタイヤエンジンでしょう。どんな車でもタイヤとエンジンが必要ですよね。この「無くてはならないもの」はインターフェースとして定義するといいでしょう。

トヨタはハイブリッドに長けているとか、日産は電気自動車などと書きましたがあくまでインターフェースを分かりやすく説明するための例えであり、誤解のないようご注意を

インターフェースの使い方

では車作りをプログラムで表すとどうのようになるか、見てみましょう。

/// <summary>
/// 車の基本パーツのインターフェース
/// </summary>
public interface IBasicPartsOfCar
{
    // タイヤを作る
    void CreateTire();

    // エンジンを作る
    void CreateEngine();
}
/// <summary>
/// トヨタ自動車
/// </summary>
public class ToyotaCars : IBasicPartsOfCar
{
    // ハイブリッド関連の何かをやる(トヨタ独自)
    public void DoSomethingHybridRelated()
    {
    }

    // タイヤを作るロジック
    public void CreateTire()
    {
    }

    // エンジンを作るロジック
    public void CreateEngine()
    {
    }
}
/// <summary>
/// 日産自動車
/// </summary>
public class NissanCars : IBasicPartsOfCar
{
    // 電気自動車関連の何かをやる(日産独自)
    public void DoSomethingElectricRelated()
    {
    }

    // タイヤを作るロジック
    public void CreateTire()
    {
    }

    // エンジンを作るロジック
    public void CreateEngine()
    {
    }
}
/// <summary>
/// ホンダ自動車
/// </summary>
public class HondaCars : IBasicPartsOfCar
{
    // 走行性能関連の何かをやる(ホンダ独自)
    public void DoSomethingDrivingPerformanceRelated()
    {
    }

    // タイヤを作るロジック
    public void CreateTire()
    {
    }

    // エンジンを作るロジック
    public void CreateEngine()
    {
    }
}
/// <summary>
/// マツダ自動車
/// </summary>
public class MazdaCars : IBasicPartsOfCar
{
    // クリーンディーゼル関連の何かをやる(マツダ独自)
    public void DoSomethingCleanDieselRelated()
    {
    }

    // タイヤを作るロジック
    public void CreateTire()
    {
    }

    // エンジンを作るロジック
    public void CreateEngine()
    {
    }
}

いかがでしょうか?
IBasicPartsOfCarを継承したクラス(ToyotaCarsなど)では、必ずvoid CreateTire()とvoid CreateEngine()、この2つの関数を実装しないといけません。実装しないとコンパイルエラーになります。(だって指示通りしないから怒られるのは当然でしょう)

インターフェースのメリット

重要なことなので何回でも書きますが、インターフェースを継承したクラスは必ずそのインターフェースで宣言した関数の実態を実装しなければなりません。これはつまりインターフェースのメリットと言っていいでしょう。
何かを実装する上で、これだけ必ず実装しないといけないといったようなケースでは、インターフェースを作ることで実装漏れ、及びコードの統一性を図られます
人間クラス(HumanClass)を作るとして、頭、胴体、手、足、(もっというと目や口など細かいのがいっぱいあるから割愛)は必ずないといけないので、インターフェースを作れば、実装漏れの心配はありません。後は人種によって、様々の特徴(目の色だったり、皮膚の色だったり、何なら原始人の場合は濃密な毛髪などといった特徴)を肉付けしていけばいいだけです。

まとめ

  • インターフェースは指示書みたいなもの
  • インターフェースで関数だけを宣言する(指示だけをする)
  • インターフェースを継承したクラスはそのインターフェースで宣言した関数のすべてを実装しないといけない(実装しないとそもそもコンパイルエラーになる)
  • インターフェースのメリットは実装漏れの防止とコードの統一性を保つこと

いかがでしょうか?自分なりにインターフェースについて解説してみました。
ご理解いただけたでしょうか?実はインターフェースのメリットの一つでコードの統一性を保つことは「ジェネリック関数」との相性はすごくいいので、是非使ってみてください。
ジェネリック関数は処理は同じだけど渡す引数(型)が異なるだけで、型の数だけ関数を作らないといけないといったようなことを解消できる仕組みです。詳細についてはこちらの記事も合わせてご一読いただければと思います。

コメント

タイトルとURLをコピーしました