PHPベストプラクティス >

オブジェクト指向言語ではないPHP5の特徴

※Java、Ruby や Pythonなどのオブジェクト指向言語から見て違和感のあるPHP5のオブジェクト指向機能*1について整理しています。

内部クラス、匿名クラスを定義できない

  • 内部クラスや匿名クラスを定義することができません。パッケージスコープもないので、通常のパブリックなクラスとして定義するしかありません。
  • クロージャもありません。
  • 匿名関数については、create_function() を使って似たことをできますが、あまりスマートではありません。

コンストラクタメソッドもサブクラスに継承される

  • PHP5では、コンストラクタメソッドも通常のメソッドと同じなので、サブクラスに継承されます。Javaでは、コンストラクタはメソッドではないので、サブクラスには継承されません。
  • PHP Commonsでは、サブクラスを Singleton 実装する余地(コンストラクタメソッドを private に制限する*2)を残すために、マジックメソッド __construct ではなく、敢えてクラスと同名のコンストラクタメソッドで定義するようにしています*3

メンバの初期化は定数で行わなければならない

  • 変数、他のメンバ、関数コール、newによるインスタンス生成などは使えません。
  • オブジェクト定数(const)や array() は使えます。
  • public static なメンバを定数以外のオブジェクトなどで初期化したい場合は、そのクラス定義の外(直後)で行うしかありません。

finalでメンバの値の変更を禁止することができない

  • クラスやメソッドに final で修飾し、継承を禁止することはできますが、メンバを final で修飾し、値の変更を禁止することはできません。
  • 前節の初期化の問題もあり、クラスで列挙型を疑似実装した場合、あまり堅牢とは言えません。

タイプヒンティングされたパラメータに null を与えることができない

  • 特定の型でタイプヒンティングされたパラメータに null を与えると、エラーが発生します。null ではないその型のインスタンスを厳密に要求するようです。

配列のキーにオブジェクトは使えない

  • 配列のキーに使えるのは、整数または文字列です。オブジェクトを含めた他の型を使えません。
  • なお、PHP5には、オブジェクトの同値性テスト契約のためのメソッド(例えば equals)やそれを担保するオブジェクトのハッシュコードを返すメソッド(例えば hashCode)の実装をすすめる機構(オーバーライドがすすめられるマジックメソッドのような仕組)はありません。
  • PHP Commons には、ルートクラスとして Commons_Lang_Object を用意していますので、このクラスを継承し、必要に応じて equals メソッドや hashCode メソッドなどをオーバーライドすることをおすすめします。

*1 PHP自体、オブジェクト指向言語とは謳ってはいない。
*2 スーパークラスのメソッドの契約を破らないために、メソッドはアクセスを緩和する方向にしかオーバーライドできません。
*3 それぞれのクラスでコンストラクタ名が異なるので、private で修飾することが可能になります

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2009-03-31 (火) 13:05:17 (3911d)