読者です 読者をやめる 読者になる 読者になる

がりらぼ

WindowsRuntimeの応援ブログ

C#の主要インターフェース解説:インターフェースとは

にゅーろにあのCoreプロジェクトをIEnumerableで返したいなとか思ったので今日から数回にわたってC#で使われる主要インターフェースについて解説したいと思います。

インターフェースとは

インターフェースと検索してみると、

二つのものが接続・接触する箇所や、両者の間で情報や信号などをやりとりするための手順や規約を定めたものを意味する

インターフェースとは 【 interface 】 【 I/F 】 - 意味/解説/説明/定義 : IT用語辞典

という意味です。

ようするにAというものからBというものへ、何かをしたいときの橋渡しとなるものがインターフェースです。

f:id:garicchi:20140911135235p:plain

Aというものから仕様もわからない、異なるBというものへ何かを送りたいときは、あいだを埋めてくれる共通の成約をつけると便利です。

例えば現実世界でいうと、人間がテレビを操作したいとするとき、テレビはコンピュータなので0と1の信号しか受け取ることができませんが人間は0と1の信号は読むことができないのでテレビを操作することができません。

そこでテレビはスイッチというインターフェースを提供しています。

「スイッチというインターフェースがボタンを押すことによってテレビを操作することができる」ということを保証しているから人間はスイッチというインターフェースを使ってテレビを操作することができるのです。

f:id:garicchi:20140911140440p:plain

このようにインターフェースは「機能を実装していることを保証しているもの」とも言い換えることもできます。

C#におけるインターフェース

C#のインターフェースも現実世界のインターフェースと概念的には大差ありません。

C#におけるインターフェースとは、「クラスとクラスの間を埋めてくれるもの」です。

あるクラスAからあるクラスBを操作したいときに機能を実装していることを保証してくれます。

実際にコードを見てみましょう。

テレビクラスと人間クラスを作って、人間クラスがテレビクラスを操作してチャンネルを変えたいと思います。

public class TV
{
    private int channel = 0;
    public TV()
    {
    }
}

public class Human
{
    public Human()
    {
    }    
}

テレビクラスはint型のchannelメンバを隠蔽しているのでHumanクラスからではTVクラスのチャンネルを操作することはできません。

これを解決するためには、「スイッチというチャンネルを切り替えてくれることを保証しているインターフェースを用意して、テレビがスイッチを実装していればよい」のです。

なのでISwitchというインターフェースを用意します。 C#のインターフェースはinterfaceというキーワードで作成し、インターフェース名はIから始まるという命名規則があります。

public interface ISwitch
{
    void ChangeChannel(int nextChannel);    //チャンネルを切り替えるという機能
}

このようにインターフェースをつくることでISwitchインターフェースは「ChangeChannelメソッドでチャンネルを切り替えることができる」ということを保証することを表します。

インターフェースを実装してみる

あとは、このISwitchインターフェースをテレビが実装していればよいのでテレビに実際にスイッチを実装してみましょう。

C#であるクラスにインターフェースを実装するにはクラス名の後ろに:をつけてインターフェース名を入れます

public class TV:ISwitch
{
    private int channel = 0;
    public TV()
    {
    }
}

しかしこのままではChangeChannelメソッドを作っていないのでテレビはチャンネル切り替えを実装していません。

ISwitchインターフェースはチャンネルをChangeChannelメソッドでチャンネルを切り替えることを保証しているのにこのままでは保証出来ていません。

なのでこのままビルドしようとするとコンパイラがエラーを出力します。

f:id:garicchi:20140911142310p:plain

C#ではちゃんとインターフェースが保証する機能を実装することを必須化することでインターフェースに信頼性を持たせています。

では実際にインターフェースの機能を実装してみましょう。

実装したいインターフェースを右クリックし、インターフェースの実装→インターフェースの実装を押します。

f:id:garicchi:20140911142607p:plain

public class TV:ISwitch
{
    private int channel = 0;
    public TV()
    {
    }

    public void ChangeChannel(int nextChannel)
    {
        throw new NotImplementedException();
    }
}

インターフェースが自動実装されました。VisualStudioはインターフェースが保証する機能を自動で作ってくれる便利な機能を持っています。

しかしこのままではChangeChannelを実行すると例外をスローしてしまします。 つまりこのテレビクラスはまだISwitchインターフェースを未実装です。

なのでちゃんとChangeChannelメソッドでチャンネルを更新しましょう。

public class TV:ISwitch
{
    private int channel = 0;
    public TV()
    {
    }

    public void ChangeChannel(int nextChannel)
    {
        this.channel = nextChannel;
    }
}

これでテレビクラスはChangeChannelメソッドでチャンネルを変える機能を実装できました

ChangeChannelメソッドでチャンネルをかえることができるということはISwitchインターフェースが保証しています。

テレビクラスはこのISwitchインターフェースを実装しているのでテレビはChangeChannelメソッドでチャンネルをかえることができます。

インターフェースを利用して別のクラスを操作する

ではHumanクラスからテレビを操作してみましょう。

public class Human
{
    public Human()
    {
    }

    public void PushChannel(int nextChannel, ISwitch tv)
    {
        tv.ChangeChannel(nextChannel);
    }
}

Humanクラスは、PushChannelメソッドでint型の次のチャンネルとISwitch型のテレビを受け取ってテレビのChangeChannelメソッドを実行しています。

ここで重要なのは引数にISwitchインターフェース型でテレビをうけとることができるということです。

C#のインターフェースは、インターフェースを実装しているクラスは実装しているインターフェースの型の変数にいれることができます

ようするにこういうことができます。

ISwitch tv=new TV();

なのでPushChannelメソッドでISwitch型の変数を引数として受け付けるということはISwitchを実装しているすべてのものを受け付けることができるということです。

したがってHumanクラス(人間)はISwitchを実装しているもの(テレビ)のチャンネルを変更することができるのです。

これを図で表すと、人間は、スイッチというインターフェースを用いてテレビにアクセスし、チャンネルを変更するというふうになります。

f:id:garicchi:20140911175926p:plain

チャンネルを変更してみる

これでチャンネルを変更する仕組みは出来上がったので実際にチャンネル変更をしてみましょう。

class Program
{
    static void Main(string[] args)
    {
        TV tv1 = new TV();
        Human human = new Human();

        human.PushChannel(3,tv1);   //テレビ1を3チャンネルに変更 


    }
}

PushChannelメソッドは第二引数でISwitchインターフェースを受け取るのでISwitchインターフェースを実装しているTVクラスを入れることができます。

このように今回はクラスのメソッドの引数の窓口としてインターフェースを使用しましたがC#には様々な既存のインターフェースがあり、それぞれのインターフェースを正しく実装することによって、クラスにいろいろな機能をもたせることができます。

次回以降ではC#のさまざまな既存インターフェースの解説を行いたいと思います。