継承

 継承は、インヘリタンスとも呼ばれます。既に用意されているオブジェクトを基に、機能などを追加して新たなオブジェクトを作ることができる機能です。

 これから、Busクラスを作成してみましょう。バスは、人を乗せて運ぶことができますが、車と同じように進んだり、止まったりすることができます。つまり、Carクラスのような機能を持っています。「バスは車である」ということができます。このような関係を「is-a」の関係といいます(Bus is a Car)。

 このような場合、BusクラスはCarクラスの機能等を引き継いで作成することができます。Carクラスを継承してBusクラスを作ることができます。このようにすることで、Busにしかない属性、機能を記述すればよくなります。つまり、CarクラスとBusクラスの差分を記述するわけです。

 継承において、もとになるクラスをスーパークラスや基底クラスといい、それをもとに新しく作成するクラスをサブクラスや派生クラスといいます。

クラス継承の書式
class サブクラス名 extends スーパークラス名
{
 各種定義…
}

 継承の指定をした後、スーパークラスにはないプロパティやメソッドを追加や修正する記述をします。

○ ファイル

Busクラスを追加して確認してみましょう。Bus.phpを追加してください。

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

サンプルダウンロード

○ プログラム

 次のように記述してください。

Bus.php

  1. //クラスファイルを読み込む
  2. require_once 'Car.php';
  3. class Bus extends Car
  4. {
  5.  //プロパティ==========
  6.  private $salesAmount = 0; //運賃
  7.  private $passengerNumber = 0; //乗客人数
  8.  //コンストラクタ==========
  9.  public function __construct($gas){
  10.   //Carクラスのコンストラクタを呼び出す
  11.   parent::__construct($gas);
  12.   //プロパティの初期化
  13.   $this -> salesAmount = 0;
  14.   $this -> passengerNumber = 0;
  15.  }
  16.  //メソッド==========
  17.  //運賃を取得する
  18.  public function getSalesAmount(){
  19.   return $this -> salesAmount;
  20.  }
  21.  //乗客人数を取得するメソッド
  22.  public function getPassengerNumber(){
  23.   return $this -> passengerNumber;
  24.  }
  25.  //乗車させるメソッド
  26.  public function rideToBus($fare){
  27.   //走行中かどうか
  28.   if($this -> getSpeed() != 0){
  29.    return '停車してください。';
  30.   }
  31.   //満席かどうか
  32.   if($this -> passengerNumber >= 50){
  33.    return '満席のため、乗車できません。';
  34.   }
  35.   //料金と、乗車人数を加算する
  36.   $this -> salesAmount += $fare;
  37.   $this -> passengerNumber++;
  38.   return null;
  39.  }
  40.  //降車させるメソッド
  41.  public function getOffBus(){
  42.   if($this -> getSpeed() != 0){
  43.    return '停車してください。';
  44.   }
  45.   //乗客がいるかどうか
  46.   if($this -> passengerNumber == 0){
  47.    return '乗客はいません。';
  48.   }
  49.   //乗車人数を減算
  50.   $this -> passengerNumber--;
  51.   return null;
  52.  }
  53. }

○ クラス図

○ 解説

 2行目でCarクラスを継承しています。これにより、Carクラスが持っているspeedUpメソッド、speedDownメソッドが使えるようになります。

 5行目のプロパティは売上金額を扱います。乗客が乗車するたびに加算されていきます。このプロパティはprivate修飾子がついているので、設定はクラス内部からしかできないようになっています。6行目のプロパティは現在の乗客数を扱います。今回は50人まで乗せられるようにプログラムで制御しています。このプロパティも設定はクラス内部からしかできないようになっています。

 9~16行目ではガソリン量を受け取るコンストラクタを定義しています。11行目はスーパークラスのコンストラクタを呼び出しています。「parent」キーワードは、スーパークラスを表します。ここでのparentキーワードはCarクラスを表します。

 30~44行目は乗車するメソッドです。このメソッドは運賃を受け取り、乗車処理をします。その際、バスが走っていたり、乗客数が満員になっていたりすると乗車できないようにしています。いずれにも当てはまらない場合は、受け取った運賃を売上金額プロパティに加算し、乗客数プロパティを1人分増やします。

 47~59行目は降車するメソッドです。バスが走っていたり、乗客がいない場合は降車できないようにしています。いずれにも当てはまらない場合は、乗客数プロパティを1人分減らします。

○ ファイル

Busクラスを利用する記述をしましょう。「StaticTest.php」ファイルをコピーして、「InheritanceTest.php」を作成してください。

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

○ プログラム

 次のように修正してください。

InheritanceTest.php

  1. <?php
  2. //クラスファイルを読み込む
  3. require_once 'Bus.php';
  4. ?>
  5. <!DOCTYPE html>
  6. <html lang="ja">
  7.  <meta charset="utf-8">
  8.  <head>
  9.   <title>Busオブジェクト実行</title>
  10.  </head>
  11.  <body>
  12. <?php
  13. //バスの状態を表示する関数
  14. function showData($bus){
  15.  print('スピード:' . $bus -> getSpeed() . 'km<br>');
  16.  print('ガソリン:' . $bus -> getGas() . 'L<br>');
  17.  print('売上金額:' . $bus -> getSalesAmount() . '円<br>');
  18.  print('乗車人数:' . $bus -> getPassengerNumber() . '人<br>');
  19. }
  20. //インスタンスを生成する
  21. $bus = new Bus(150);
  22. //加速してみる
  23. print('加速します!<br>');
  24. $bus -> SpeedUp(5);
  25. showData($bus);
  26. print('<hr>');
  27. //乗車する
  28. print('乗車します!<br>');
  29. $ret = $bus -> rideToBus(200);
  30. if($ret != null){
  31.  print('<span style="color:red">' . $ret . '</span><br>');
  32. }
  33. //減速してみる
  34. print('減速します!<br>');
  35. $bus -> SpeedDown(5);
  36. showData($bus);
  37. print('<hr>');
  38. //乗車する
  39. print('乗車します!<br>');
  40. $ret = $bus -> rideToBus(200);
  41. if($ret != null){
  42.  print('<span style="color:red">' . $ret . '</span><br>');
  43. }
  44. showData($bus);
  45. print('<hr>');
  46. //加速してみる
  47. print('加速します!<br>');
  48. $bus -> SpeedUp(5);
  49. showData($bus);
  50. print('<hr>');
  51. //降車する
  52. print('降車します!<br>');
  53. $ret = $bus -> getOffBus();
  54. if($ret != null){
  55.  print('<span style="color:red">' . $ret . '</span><br>');
  56. }
  57. showData($bus);
  58. print('<hr>');
  59. //減速してみる
  60. print('減速します!<br>');
  61. $bus -> SpeedDown(5);
  62. showData($bus);
  63. print('<hr>');
  64. //降車する
  65. print('降車します!<br>');
  66. $ret = $bus -> getOffBus();
  67. if($ret != null){
  68.  print('<span style="color:red">' . $ret . '</span><br>');
  69. }
  70. showData($bus);
  71. print('<hr>');
  72. //降車する
  73. print('降車します!<br>');
  74. $ret = $bus -> getOffBus();
  75. if($ret != null){
  76.  print('<span style="color:red">' . $ret . '</span><br>');
  77. }
  78. showData($bus);
  79. print('<hr>');
  80. ?>
  81.  </body>
  82. </html>

○ 実行結果

実行結果
実行結果

○ 解説

 22行目でBusオブジェクトを生成しています。BusオブジェクトはCarクラスを継承しているので今まで通り加速したり、減速したりできます。32、45行目では乗車メソッドを呼び出しています。戻り値がnullでない場合はエラーメッセージが返って来ているので、メッセージとして表示しています。60、75、84行目では降車メソッドを呼び出しています。このメソッドは乗車メソッドと同様にエラーメッセージかnullが返ってくるのでそれに応じた処理をしています。

 今回はCarクラスを基にBusクラスを作成しました。BusクラスはCarクラスを継承しているので、Carクラスのメンバを記述しなくても使用することができます。ただし、privateになっているメンバは、継承したクラスでも直接アクセスすることができません。「protected」にすれば、直接操作できます。「protected」は、継承関係であればアクセスできますが、外部クラスからはアクセスすることができません。

 PHPでは、サブクラスは1つのクラスから継承することができます。複数のクラスから継承させることはできません。(多重継承の禁止)

Busクラスのイメージ
Busクラスのイメージ

 Busクラスのインスタンスを生成するときにBusクラスのコンストラクタを呼び出します。サブクラスのコンストラクタでスーパークラスのコンストラクタを明示的に呼び出す場合は「Parent::__construct()」のように記述します。

インスタンス生成の手順
インスタンス生成の手順

前へ   次へ