インターフェイスとポリモーフィズム

 インターフェイスは抽象メソッドで構成され、実装したクラスで具象化(実際の処理を定義)します。そのため、プログラムの仕様を作るように扱うことができます。

 例えば、パソコンなどについているUSB(Universal Serial Bus)は規格または仕様であって、何かの部品そのものを指すわけではありません。USBの仕様を実装しているパソコンや、記憶装置、携帯端末などがあります。同じ仕様を実装している物同士、つなげていろいろなことができます。

USBは様々な種類のものに実装されている
USBは様々な種類のものに実装されている

 USBを実装しているものはそれぞれ別々に設計され、作られている点に注目してください。パソコンを作るときには、USBを実装している部品を差し込めるようにUSBで規定されているサイズの差込口を用意し、差し込んだ部品からどのようにデータなどを読み書きするかを具体的に設計して、製造します。USBを実装している部品は必ずUSBで規定されているサイズの接続部を持っていて、何らかの処理を行えると仮定してパソコンを設計・製造することができます。

 インターフェイスも同様に、プログラム上の仕様を策定して、それぞれのクラスで実装させることによって個々のクラスを作りやすくすることができます。

 ではこれから、IDripインターフェイスを実装したいくつかの種類の飲み物を作ってみましょう。また、IDripインターフェイスを実装した飲み物を扱うことのできるドリッパーマシンも作成してみましょう。

○ プロジェクト

 プロジェクトを作成して確認してみましょう。

プロジェクトの種類 コンソール アプリケーション
プロジェクト名 InterfacePlymoTest

サンプルダウンロード

○ 作成の準備

 「InterfaceTest」プロジェクトを修正して作成しましょう。InterfaceTestフォルダーをコピーして、作成するプロジェクト名にフォルダー名を変更してください。

○ プログラム

 IDripインターフェイスを実装したTeaクラスを作成してください。

Tea.cs

  1. class Tea
  2.  : IDrip
  3. {
  4.  private string name = "ティー";
  5.  public string Drip()
  6.  {
  7.   return this.name;
  8.  }
  9.  public string DripWithMilk()
  10.  {
  11.   return "ミルク" + this.name;
  12.  }
  13. }

○ クラス図

○ 解説

 14~17行目では、IDripインターフェイスのDripメソッドをオーバーライドしています。このメソッドはフィールドに設定されている飲み物を返します。今回は紅茶が注がれるイメージとして文字列を返しています。

 19~22行目では、IDripインターフェイスのDripWithMilkメソッドをオーバーライドしています。このメソッドはミルクと紅茶を返すことでミルクティーを注ぎます。

○ プログラム

 次に、ドリップする機械を表すDripperクラスを作成しましょう。次にようにクラスを作成してください。

Dripper.cs

  1. class Dripper
  2. {
  3.  private bool milkflag = false;  //ミルクを注ぐ場合:true 注がない場合:false
  4.  public void setMilkStatus(bool flag)
  5. {
  6.   this.milkflag = flag;
  7.  }
  8.  //セットした飲み物を注ぐメソッド
  9.  public string DripDrink(IDrip drink)
  10.  {
  11.   if (milkflag)
  12.   {
  13.    return drink.DripWithMilk();
  14.   }
  15.   else
  16.   {
  17.    return drink.Drip();
  18.   }
  19.  }
  20. }

○ クラス図

○ 解説

 11行目では、飲み物を注ぐときにミルクも一緒に注ぐかどうかの状態を保持するフィールドが定義されています。13~16行目のメソッドでその状態を設定します。

 19~29行目で飲み物を注ぎます。その時に注ぐ飲み物のオブジェクトを渡すようになっています。ここで注目できるのは引数の型が「IDrip」型であるという点です。この型を実装しているオブジェクトであればセットできます。この仕組みにより、このドリッパーがある特定の飲み物用のものではなく、IDripという仕様を実装している飲み物であればこのドリッパーを使うことができます。このような仕組みのため、ドリッパークラスは具体的にどんな飲み物がセットされるかを意識せずに設計することができるわけです。

○ プログラム

 では次にMainメソッドを修正しましょう。

Program.cs

  1. static void Main(string[] args)
  2. {
  3.  //ドリッパーオブジェクトを生成
  4.  Dripper dripper = new Dripper();
  5.  while (true)
  6.  {
  7.   //メニューを入力
  8.   Console.WriteLine("飲み物を選んでください。");
  9.   Console.Write("1)珈琲 2)紅茶 9)終了:");
  10.   string drink = Console.ReadLine();
  11.   if (drink == "9")
  12.   {
  13.    //プログラムを終了する
  14.    return;
  15.   }
  16.   Console.Write("ミルクは注ぎますか(Y/N):");
  17.   string milk = Console.ReadLine();
  18.   //ミルクの状態をドリッパーにセットする
  19.   if (milk == "Y")
  20.   {
  21.    dripper.setMilkStatus(true);
  22.   }
  23.   else if (milk == "N")
  24.   {
  25.    dripper.setMilkStatus(false);
  26.   }
  27.   //入力内容によって分岐する
  28.   string cup = "";
  29.   switch (drink)
  30.   {
  31.    case "1":
  32.     //珈琲を注ぐ
  33.     cup = dripper.DripDrink(new Coffee());
  34.     break;
  35.    case "2":
  36.     //紅茶を注ぐ
  37.     cup = dripper.DripDrink(new Tea());
  38.     break;
  39.   }
  40.   //カップの中身を表示する
  41.   Console.WriteLine("カップには{0}が入っています。", cup);
  42.  }
  43. }

○ 解説

 14行目では、ドリッパーオブジェクトを作成しています。その後、メニューを表示して、珈琲か紅茶を選びます。そして、ミルクを注ぐかどうかを入力します。ミルクを注ぐ場合は35行目にある、ドリッパーオブジェクトのSetMilkStatusメソッドにtrueをセットしてミルクを注ぐ準備をさせます。注がない場合は39行目にある、ドリッパーオブジェクトのSetMilkStatusメソッドにfalseをセットしてミルクの設定を解除します。

 43行目では飲み物を注ぐためのカップを用意しています。44~54行目では選択した飲み物に応じて処理を分岐しています。珈琲を選択した場合は、48行目の処理が実行されます。この処理はドリッパーオブジェクトのDripDrinkメソッドを呼び出す時にコーヒーオブジェクトを生成して渡しています。結果として珈琲が注がれます。なお、ミルクを注ぐ準備がされている場合はミルクコーヒーが注がれます。52行目ではティーオブジェクトを生成して、紅茶を注いでいます。そして、57行目でカップの中身を表示しています。

○ 実行結果

飲み物を選んでください。
1)珈琲 2)紅茶 9)終了:1
ミルクは注ぎますか(Y/N):Y
カップにはミルクコーヒー(微糖)が入っています。
飲み物を選んでください。
1)珈琲 2)紅茶 9)終了:1
ミルクは注ぎますか(Y/N):N
カップにはコーヒーが入っています。
飲み物を選んでください。
1)珈琲 2)紅茶 9)終了:2
ミルクは注ぎますか(Y/N):N
カップにはティーが入っています。
飲み物を選んでください。
1)珈琲 2)紅茶 9)終了:2
ミルクは注ぎますか(Y/N):Y
カップにはミルクティーが入っています。
飲み物を選んでください。
1)珈琲 2)紅茶 9)終了:9
(終了)

前へ   次へ