抽象クラス

 ポリモーフィズムを実現させるにはいくつかの方法があります。ここでは、抽象クラスについてみてみましょう。抽象クラスは、抽象メソッドを含むクラスです。抽象メソッドとは、処理を定義していないメソッド、つまり、メソッド名、引数リストのみ宣言されているメソッドです。抽象メソッドは「abstract」キーワードをつけて宣言します。 アクセス権には「public」か「protected」を指定します。

抽象メソッド定義の書式
abstract アクセス権 function メソッド名(引数リスト);

 抽象メソッドを持つクラスは具現化しないと使えないため、クラスに「abstract」キーワードをつける必要があります。それにより、抽象クラスとします。

抽象クラス定義の書式
abstract class クラス名
{
 各種定義…
}

 抽象クラスはインスタンスを生成できません。別のクラスで継承し、抽象メソッドをオーバーライドして利用することができるようになります。

○ ファイル

 抽象クラスを作成しましょう。今回は乗り物を表すクラスを作成します。今まで作成したCarクラスを乗り物(Vehicle)クラスとして、加速処理部分を抽象化したクラスを作成することとします。これにより加速部分はそれぞれの種類の乗り物によって定義することになります。Vehicle.phpファイルを追加してください。

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

サンプルダウンロード

○ プログラム

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

Vehicle.php

  1. <?php
  2. abstract class Vehicle
  3. {
  4.  //プロパティ==========
  5.  protected $speed = 0; //スピード情報
  6.  protected $gas = 0.0; //ガソリン情報
  7.  //コンストラクタ==========
  8.  public function __construct($gas){
  9.   $this -> speed = 0;
  10.   $this -> gas = $gas;
  11.  }
  12.  //メソッド==========
  13.  //加速するメソッド(抽象メソッド)
  14.  abstract public function speedUp($sp);
  15.  //減速するメソッド
  16.  public function speedDown($sp){
  17.   //スピードを減らす
  18.   $this -> speed -= $sp;
  19.   if($this -> speed < 0){ //スピードがマイナスになる場合
  20.    //スピードを0に補正する
  21.    $this -> speed = 0;
  22.   }
  23.  }
  24.  //スピード情報を取得するメソッド
  25.  public function getSpeed(){
  26.   return $this -> speed;
  27.  }
  28.  //ガソリン情報を取得するメソッド
  29.  public function getGas(){
  30.   return $this -> gas;
  31.  }
  32. }

○ クラス図

○ 解説

 16行目では、抽象メソッドを宣言しています。メソッドの仕様は決まっているので、このメソッドを使用するにはオーバーライドして処理を実装する必要があります。抽象メソッドが含まれるために2行目のクラスの宣言に「abstract」キーワードがついており、抽象クラスとして作成しています。

○ ファイル

 次に、乗り物クラスを継承したスポーツカークラスを作成しましょう。

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

○ プログラム

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

SportsCar.php

  1. <?php
  2. //クラスファイルを読み込む
  3. require_once 'Vehicle.php';
  4. class SportsCar extends Vehicle
  5. {
  6.  //プロパティ==========
  7.  const MAXSPEED = 300; //最大スピード
  8.  const MAXFUEL = 60; //ガソリンタンク容量
  9.  //コンストラクタ==========
  10.  public function __construct($gas){
  11.   //Vehicleクラスのコンストラクタを呼び出す
  12.   parent::__construct($gas);
  13.   //ガソリン量が容量を超える場合は、最大容量をガソリン量にセットする
  14.   if($this -> gas > self::MAXFUEL){
  15.    $this -> gas = self::MAXFUEL;
  16.   }
  17.  }
  18.  //メソッド==========
  19.  public function speedUp($sp){
  20.   //ガソリンを減らす
  21.   $this -> gas -= $sp / 10.0;
  22.   if($this -> gas < 0){ //ガソリンがマイナスになる場合
  23.    //ガソリンを0に補正し、スピードを増やさない
  24.    $this -> gas = 0;
  25.   }else{
  26.    //スピードを増やす
  27.    $this -> speed += $sp;
  28.    if($this -> speed > self::MAXSPEED){
  29.     $this -> speed = self::MAXSPEED;
  30.    }
  31.   }
  32.  }
  33. }

○ クラス図

○ 解説

 8行目と9行目では最大スピードと、ガソリンタンク容量を定数として宣言しています。

 12~20行目ではコンストラクタを定義しています。このコンストラクタはガソリン量を受けとって、スーパークラスのコンストラクタを呼び出し、ガソリン量をセットしています。そのあと、ガソリンタンク容量と比較して、セットしたガソリン量が多ければ最大容量をセットするという処理をします。

 23~36行目ではspeedUpメソッドをオーバーライドしています。抽象クラスを継承すると、抽象メソッドは必ずオーバーライドしなければならないという義務が発生します。今回は加速するときに、消費するガソリン量がない場合は加速しない、最大スピードに達していた場合はそれよりスピードが出ないようにしています。

○ ファイル

 では次にSportsCarクラスを利用するプログラムを作成しましょう。

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

○ プログラム

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

AbstractClassTest.php

  1. <?php
  2. //クラスファイルを読み込む
  3. require_once 'SportsCar.php';
  4. ?>
  5. <!DOCTYPE html>
  6. <html lang="ja">
  7.  <meta charset="utf-8">
  8.  <head>
  9.   <title>SportsCarオブジェクト実行</title>
  10.  </head>
  11.  <body>
  12. <?php
  13. //車・バスを加速して状態を表示する関数
  14. function showData($vehicle){
  15.  //状態を表示する
  16.  print('スピード:' . $vehicle -> getSpeed() . 'km<br>');
  17.  print('ガソリン:' . $vehicle -> getGas() . 'L<br>');
  18. }
  19. //車インスタンスを生成する
  20. $car = new SportsCar(60);
  21. //現在の状態を表示する
  22. showData($car);
  23. print('<hr>');
  24. //加速してみる
  25. print('加速します!<br>');
  26. $car -> SpeedUp(50);
  27. showData($car);
  28. print('<hr>');
  29. //加速してみる
  30. print('加速します!<br>');
  31. $car -> SpeedUp(50);
  32. showData($car);
  33. print('<hr>');
  34. //減速してみる
  35. print('減速します!<br>');
  36. $car -> SpeedDown(50);
  37. showData($car);
  38. print('<hr>');
  39. //減速してみる
  40. print('減速します!<br>');
  41. $car -> SpeedDown(50);
  42. showData($car);
  43. print('<hr>');
  44. ?>
  45.  </body>
  46. </html>

○ 解説

 29、35行目では、SportsCarオブジェクトのspeedUpメソッドを呼び出しています。このメソッドはSportsCarクラスでオーバーライドされています。それにより、SportsCarで定義されているspeedUpが実行されます。

○ 実行結果

実行結果
実行結果

前へ   次へ