カプセル化

 今まで作成したサンプルは、危険が潜んでいます。それは、スピードやガソリン残量を直接指定することができるという点です。急発進や、急停車、走行中にもかかわらず、ガソリン残量を変更できてしまいます。このままでは、完成されたオブジェクトとは言えません。

フィールドに自由にアクセスできる
フィールドに自由にアクセスできる

 そこで、オブジェクト指向の特徴のひとつである「カプセル化」を使用して、安全なクラスを作成しましょう。クラスを定義する際に、アクセス権を指定することにより、カプセル化を行うことができます。アクセス権は以下のような指定ができます。

アクセス権 意味
public クラスの内部・外部問わず、自由にアクセスすることができます。アクセス制限のレベルが最も低いアクセス権です。
protected クラスの内部と、派生したクラスからはアクセスすることができます。
private クラスの内部からしかアクセスすることができません。アクセス制限のレベルが最も高いアクセス権です。
アクセス権一覧

○ ファイル

 Carクラスを修正して確認してみましょう。

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

サンプルダウンロード

○ プログラム

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

Car.php

  1. class Car
  2. {
  3.  //プロパティ==========
  4.  //public $speed = 0; //スピード情報
  5.  private $speed = 0; //スピード情報(修正)
  6.  //public $gas = 0.0; //ガソリン情報
  7.  private $gas = 0.0; //ガソリン情報(修正)
  8.  //メソッド
  9.  //加速させるメソッド
  10.  public function speedUp($sp){

○ クラス図

○ 解説

 5行目と8行目のプロパティのアクセス権は「public」を指定していたため、外部のクラスから直接アクセスできました。今回は、カプセル化をするために一旦これらの行をコメントアウトしてプログラムから外しています。6行目と9行目でアクセス権を「private」に変更することにより、外部のクラスからアクセスすることができなくなります。

カプセル化によりアクセスできなくなる
カプセル化によりアクセスできなくなる

 すると、このクラスを利用する記述の部分で変化が生じます。プロパティに値を代入したり、参照したりする記述ができなくなります。そのため、必要であればメソッドとして値を代入したり、参照したりする機能を追加しなくてはなりません。

実行してみるとエラーが表示される
実行してみるとエラーが表示される

○ プログラム

 次のようにCarクラスにメソッドを追加してください。

Car.vb

  1.  //減速させるメソッド
  2.  public function speedDown($sp){
  3.   //スピードを減らす
  4.   $this -> speed -= $sp;
  5.    //スピードを0に補正する
  6.    $this -> speed = 0;
  7.   }
  8.  }
  9.  //初期化を行うメソッド
  10.  public function init($gas){
  11.   $this -> speed = 0;
  12.   $this -> gas = $gas;
  13.  }
  14.  
  15.  //スピードを取得する
  16.  public function getSpeed(){
  17.   return $this -> speed;
  18.  }
  19.  //ガソリン残量を取得する
  20.  public function getGas(){
  21.   return $this -> gas;
  22.  }
  23. }

○ クラス図

○ 解説

 Carクラスを利用するクラスからプロパティに代入することで初期化をしていましたが、カプセル化によりプロパティにアクセスできなくなったために、36~39行目ではプロパティを初期化する手続きを用意しました。引数にガソリン量を受け取り、スピード情報を「0km」に、ガソリン量を引数のデータで初期化しています。

 また、Carクラスを利用する関数からプロパティを直接参照してスピード情報やガソリン量を取得していましたが、カプセル化によりプロパティにアクセスできなくなったために、42~44行目ではスピードを戻り値として返す手続きを、47~49行目ではガソリン量を戻り値として返す手続きを用意しました。

○ ファイル

 では、Carオブジェクトを生成して利用しているプログラムも修正しましょう。「InstanceTest.php」ファイルをコピーして、「CapsuleTest.php」を作成してください。

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

○ プログラム

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

CapsuleTest.php

  1. //車の状態を表示する関数
  2. function showData($car){
  3.  //print('スピード:' . $car -> speed . 'km<br>');
  4.  print('スピード:' . $car -> getSpeed() . 'km<br>');
  5.  //print('ガソリン:' . $car -> gas . 'L<br>');
  6.  print('ガソリン:' . $car -> getGas() . 'L<br>');
  7. }
  8. //インスタンスを生成する
  9. $car = new Car();
  10. //プロパティを初期化する
  11. //$car -> speed = 0;
  12. //$car -> gas = 20.0;
  13. $car -> init(20);

○ 実行結果

実行結果
実行結果

○ 解説

 15、18行目では、Carクラスのカプセル化によりプロパティにアクセスできなくなったためにエラーとなります。そのため、コメントアウトしています。その代わりに16、19行目で新たに手続きとして用意されたスピードやガソリン量を取得するメソッドを呼び出しています。

 26、27行目では、Carクラスのカプセル化によりプロパティにアクセスできなくなったためにエラーとなります。そのため、コメントアウトしています。その代わりに28行目で新たに手続きとして用意された初期化を行なうメソッドを呼び出しています。

 このようにカプセル化をすることにより、クラスの利用者側から直接データを参照・設定できなくすることにより、クラス作成者の意図に沿わない方法で使用されるのを避けることができます。手続きを用意することによって必要な処理をさせることができます。また、クラスを利用する側も特に意識することなく安全に、クラスを利用することができるようになります。

カプセル化したプロパティにアクセスするメソッドを用意
カプセル化したプロパティにアクセスするメソッドを用意

 一般的に、プロパティはprivate指定で非公開にして、メソッドをpublicで公開にします。ただし、内部処理などで使うメソッドはprivateにして、外部から利用されないようにします。

前へ   次へ