PHPの基礎 - クラス

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動

概要

クラスとは、何かを実行する物体の設計図のようなものである。
そして、クラスの仕様を決めるものがメソッドとメンバ変数である。

ここでは、メソッドとメンバ変数の記述方法やその他で記述可能なものについて記載する。


クラスの定義

クラスの定義を以下に示す。

 class クラス名
 {
    // ...略
 }


クラスからインスタンスを生成するには、new演算子を使用する。

変数名 = new クラス名(引数);



メンバ変数とメソッド

クラスには、値を保存するためのメンバ変数とクラスで行う処理を記述するメソッドがある。

メンバ変数は、クラス内で値を保持するために使用する。
メンバ変数の記述方法は、以下の通りである。

 class クラス名
 {
    アクセス修飾子 メンバ変数名;
 }


メソッドは、設計したクラスで実行する処理を関数の形で記述する。
メソッドの記述方法は、以下の通りである。

 class クラス名
 {
    アクセス修飾子 function メソッド名()
    {
       // メソッドで行う処理
    }
 }


以下の例では、テレビクラスを定義している。

 class Television
 {
    private $channelNo;
 
    public function dispChannel()
    {
       print('現在のチャンネルは'.$this->channelNo);
    }
 }
 
 $tv = new Television();


以下の例では、テレビクラスのインスタンスを生成して、メンバ変数にチャンネル番号を代入している。

 $tv = new Television();
 $tv->channelNo = 8;


以下の例では、クラスのメソッドを実行している。

 $tv = new Television();
 $tv->channelNo = 8;
 $tv->dispChannel();



引数があるメソッド

メソッドには引数をとることもできる。

 class クラス名
 {
    アクセス修飾子 function メソッド名(引数1, 引数2, ...)
    {
       // クラスの中で行う処理
    }
 }


なお、クラス内でメンバ変数にアクセスする場合は、thisを使用して以下のように記述する。

$this->メンバ変数名;


以下の例では、テレビクラスび新しいチャンネルを設定するメソッドを定義している。
setChannelメソッド内で、引数で渡された値をメンバ変数に代入して、クラス内のdispChannelメソッドを実行して、チャンネルを表示している。

 class Television
 {
    private $channelNo;
 
    private function dispChannel()
    {
       print('現在のチャンネルは'.$this->channelNo);
    }
 
    public function setChannel($channel)
    {
       $this->channelNo = $channel;
       $this->dispChannel();
    }
 }
 
 $tv = new Television();
 $tv->setChannel(5);



アクセス修飾子

アクセス修飾子とは、メンバ変数やメソッドのアクセス可能な範囲を指定するもので、publicprivateprotectedの3種類がある。
アクセス修飾子を指定しない場合は、publicが指定されたものとみなされる。

各アクセス修飾子のアクセス権は、以下の通りである。

  • public
    クラス内、クラス外のどこからでもアクセス可能。
  • private
    同じクラス内からのみアクセス可能。
  • protected
    同じクラス、及び子クラスからアクセス可能。
    protectedはクラスを継承する場合に関係するものである。


アクセス修飾子は、クラス外には見せたくない情報を守ることができる。
また、外部から直接呼び出す必要が無いメソッドに対しても、呼び出せないようにすることも明確にできる。

これにより、誤った使用を未然に防止することやメンバ変数とメソッドの意味を理解しやすくなる。


メンバ変数へのアクセスとメンバメソッドからの値の取得

アクセス修飾子を設定したメンバ変数へのアクセス方法について記載する。

メンバ変数を外部から直接設定できる場合は不適切な値が代入できるため、
メンバ変数をprivateにして、メンバ変数の変更はメソッド経由でのみ可能にする。
メソッド経由で設定することで事前に値の範囲を確認することができるため、不適切な値が代入される危険性が無くなる。

また、メンバ変数の値を取得できるメソッドを別途定義することで、メンバ変数の値を取得できるようにする。

 class Television()
 {
    private $channelNo;
 
    public function setChannel($channel)
    {
       if(($channel >= 1) and ($channel <= 12))
       {
          $this->channelNo = $channel;
       }
    }
 
    public function getChannel()
    {
       return $this->channelNo;
    }
 }
 
 $tv = new Television();
 $tv->setChannelNo(20);
 print('現在のチャンネルは'.$tv->getChannel());



クラス内の定数

クラスでは、定数を定義することができる。

構文は以下の通りである。

 class クラス名
 {
    const 定数名 = ;
 }


通常の定数を定義する場合はdefineを使用するが、クラス内で定数を定義する場合は、constの後に定数名を指定して値を定義する。
変数のように$マークは付かないことに注意すること。

クラス内からクラス内の定数を参照するには、self::定数名のように記述する。

※注意
selfはカレントクラスを表す。($thisはインスタンス単位)
クラス内の定数は、クラス単位で設定されている値だからである。

 class クラス名
 {
    const 定数名 = ;
 
    public function メソッド名()
    {
       print(self::定数名);
    }
 }


以下の例では、チャンネル番号を指定して、1〜12番の場合はチャンネル番号を表示、それ以外の場合はエラーを表示している。

 $tv = new Television();
 $tv->setChannel(20);
 print('現在のチャンネルは'.$tv->getChannel().'<br>');
 
 $tv->setChannel(10);
 print('現在のチャンネルは'.$tv->getChannel().'<br>');
 
 class Television
 {
    private $channelNo = 8;
 
    const MAX_CHANNEL = 12;
    const MIX_CHANNEL = 1;
    const ERROR_MSG = 'チャンネルは1から12の間で設定して下さい<br>';
 
    public function setChannel($channel)
    {
       if(($channel >= self::MIX_CHANNEL) && ($channel <= self::MAX_CHANNEL))
       {
          $this->channelNo = $channel;
       }
       else
       {
          print(self::ERROR_MSG);
       }
    }
 
    public function getChannel()
    {
       return $this->channelNo;
    }
 }



コンストラクタ

コンストラクタとは、クラスからインスタンスを生成する時に自動的に呼び出されるメソッドである。
インスタンス生成時において、コンストラクタに初期化処理等を記述することで、自動的に実行される。

コンストラクタの構文は以下の通りである。
メソッド名を__constructと記述することで、コンストラクタとなる。

 class クラス名
 {
    public function __construct(変数, 変数, ...)
    {
       // コンストラクタ内で実行する処理
    }
 }


以下の例では、コンストラクタの使用例である。

 $tv = new Television();
 
 class Television
 {
    private $channelNo;
 
    public function __construct($channel)
    {
       $this->channelNo = $channel;
    }
 }


※注意
PHPにおいて、コンストラクタを複数定義することができない。
したがって、コンストラクタはクラスごとに1つのみ定義することができる。


継承

継承は、既存のクラス (親クラス) の機能を新しいクラス (子クラス) に引き継ぐ機能である。
extendsキーワードを使用して継承を実装する。

使用できるアクセス修飾子を以下に示す。

  • public
    どこからでもアクセス可能
  • protected
    そのクラスと継承したクラスからアクセス可能
  • private
    そのクラス内からのみアクセス可能


PHPにおいて、継承で可能なことを以下に示す。

  • 親クラスのメソッドと属性を再利用
  • メソッドのオーバーライド(上書き)
  • 新しいメソッドや属性の追加
  • parent::を使用して親クラスのメソッドにアクセス


PHPにおける継承の特徴を以下に示す。

  • PHPは単一継承のみをサポートする。
    多重継承は不可。(1つのクラスは1つの親クラスしか持てない)
  • インターフェースを使用することで複数の型を実装できる。
  • finalキーワードを使用することで継承を禁止できる。


finalキーワードを使用するシーンを以下に示す。

  • セキュリティ上の理由でメソッドの動作を固定する場合
  • クラスの機能を拡張させたくない場合
  • コアとなる機能の一貫性を保持する場合


 // class.phpファイル
 
 // 基底クラス (親クラス)
 class Animal
 {
    protected $name;
    protected $age;
 
    public function __construct($name, $age)
    {
       $this->name = $name;
       $this->age  = $age;
    }
 
    public function makeSound()
    {
       return "何かの音を出す";
    }
 
    public function getInfo()
    {
       return "名前: {$this->name}, 年齢: {$this->age}歳";
    }
 }
 
 // 派生クラス (子クラス)
 // finalクラス : このクラスは継承不可
 final class Dog extends Animal
 {
    private $breed;
 
    public function __construct($name, $age, $breed)
    {
       parent::__construct($name, $age);
       $this->breed = $breed;
    }
 
    // メソッドのオーバーライド
    public function makeSound()
    {
       return "ワンワン!";
    }
 
    // 新しいメソッドの追加
    public function getBreed()
    {
       return $this->breed;
    }
 
    // 親クラスのメソッドを拡張
    public function getInfo()
    {
       return parent::getInfo() . ", 犬種: {$this->breed}";
    }
 }
 
 // 以下のコードはエラーになる
 // Fatal error: Class SportsCar may not inherit from final class Car
 //class SportsCar extends Car {
 //   public function getType()
 //   {
 //      return "スポーツカー";
 //   }
 //}


 // 使用例 : index.phpファイル
 
 require_once(__DIR__ . '/class.php');
 
 $dog = new Dog("ポチ", 3, "柴犬");
 echo $dog->getInfo() . "\n";    // 名前: ポチ, 年齢: 3歳, 犬種: 柴犬
 echo $dog->makeSound() . "\n";  // ワンワン!