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

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

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

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

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

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

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

○ ファイル

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

ファイルの種類 PHPファイル
ファイル名 Tea.php

サンプルダウンロード

○ プログラム

 次のようにプログラムを記述してください。

Tea.php

  1. <?php
  2. //インターフェイスファイルを読み込む
  3. require_once 'IDrip.php';
  4. class Tea implements IDrip
  5. {
  6.  //プロパティ
  7.  private $name = 'ティー';
  8.  //注ぐメソッドをオーバーライド
  9.  public function drip(){
  10.   return $this -> name;
  11.  }
  12.  //ミルクと一緒にそそぐメソッドをオーバーライド
  13.  public function dripWithMilk(){
  14.   return 'ミルク' . $this -> name;
  15.  }
  16. }

○ クラス図

○ 解説

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

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

○ ファイル

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

ファイルの種類 PHPファイル
ファイル名 Dripper.php

○ プログラム

 次のようにクラスを作成してください。

Dripper.php

  1. <?php
  2. class Dripper
  3. {
  4.  //プロパティ==========
  5.  private $milkflag = false; //ミルクを注ぐ場合:true 注がない場合:false
  6.  //メソッド
  7.  //ミルク注入の可否を設定するメソッド
  8.  public function setMilkStatus($flag){
  9.   $this -> milkflag = $flag;
  10.  }
  11.  //セットした飲み物を注ぐメソッド
  12.  public function dripDrink($drink){
  13.   if($this -> milkflag){
  14.    return $drink -> dripWithMilk();
  15.   }else{
  16.    return $drink -> drip();
  17.   }
  18.  }
  19. }

○ クラス図

○ 解説

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

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

○ ファイル

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

ファイルの種類 PHPファイル
ファイル名 InterfacePolymoTest.php

○ プログラム

 次のようにプログラムを記述してください。

InterfacePolymoTest.php

  1. <?php
  2. //クラスファイルを読み込む
  3. require_once 'Coffee.php';
  4. require_once 'Tea.php';
  5. require_once 'Dripper.php';
  6. ?>
  7. <!DOCTYPE html>
  8. <html lang="ja">
  9.  <meta charset="utf-8">
  10.  <head>
  11.   <title>喫茶マシーン</title>
  12.  </head>
  13.  <body>
  14. <?php
  15. //ドリッパーオブジェクトを生成する
  16. $dripper = new Dripper();
  17. //コーヒーオブジェクトを生成する
  18. $coffee = new Coffee();
  19. //紅茶オブジェクトを生成する
  20. $tea = new Tea();
  21. //ドリッパーにミルクを注ぐようにセットする
  22. print('ミルクを注ぐ機能:ON');
  23. $dripper -> setMilkStatus(true);
  24. //コーヒーを注いでみる
  25. print('コーヒーをセットして注ぎます。<br>');
  26. print($dripper -> dripDrink($coffee) . '<br>');
  27. print('<br>');
  28. //紅茶を注いでみる
  29. print('紅茶をセットして注ぎます。<br>');
  30. print($dripper -> dripDrink($tea) . '<br>');
  31. print('<hr>');
  32. //ドリッパーにミルクを注がないようにセットする
  33. print('ミルクを注ぐ機能:OFF');
  34. $dripper -> setMilkStatus(false);
  35. //コーヒーを注いでみる
  36. print('コーヒーをセットして注ぎます。<br>');
  37. print($dripper -> dripDrink($coffee) . '<br>');
  38. print('<br>');
  39. //紅茶を注いでみる
  40. print('紅茶をセットして注ぎます。<br>');
  41. print($dripper -> dripDrink($tea) . '<br>');
  42. ?>
  43.  </body>
  44. </html>

○ 解説

 16行目では、ドリッパーオブジェクトを作成しています。その後、26行目では、ドリッパーオブジェクトのsetMilkStatusメソッドにtrueをセットしてミルクを注ぐ準備をさせます。39行目では、ドリッパーオブジェクトのsetMilkStatusメソッドにfalseをセットしてミルクの設定を解除しています。

 30、44行目はドリッパーオブジェクトのdripDrinkメソッドを呼び出す時にコーヒーオブジェクトを生成して渡しています。結果として珈琲が注がれます。なお、ミルクを注ぐ準備がされている場合はミルクコーヒーが注がれます。35、49行目ではティーオブジェクトを生成して、紅茶を注いでいます。

前へ   次へ