twitterこの広告は、90日以上更新していないブログに表示しています。alpha1がリリースされた。このリリースでは、PHPのオブジェクト指向言語の新たな機能としてtraitと呼ばれる機能が追加された。PHP5.4におけるtraitとは、型に影響を与えずにクラスに適用できるメソッドとプロパティの集合である。alpha1をインストールし、traitを使ってシングルトンパターンを実装した。このコードでは、クラスの継承関係に影響を与えずにシングルトンパターンをモジュール化している。traitは、それを使うクラスがどのクラスを継承していてもどのインターフェイスを実装していても関係なく利用できる。上で書いたtraitは以下のように使える。コンストラクタを直接呼び出すとエラーgetInstanceというメソッド名が気に入らないなら、以下のようにasキーワードを用いてエイリアスを設定することも出来る。MyHoge::singleton();また、シングルトンなオブジェクトを保持したいが、コンストラクタからインスタンス化したい、という場合は以下のようにasキーワードを用いてメソッド属性の変更を行う。cloneを禁止したくない場合は単純にtraitのメソッドをオーバーライドする。cloneした際も例外は出ないtraitは型に影響を与えずにクラスが利用出来るメソッドやプロパティの集合である、と書いた。これはどういう事なのか。今回追加されたtraitの立ち位置を言う前に、まずPHPに以前から実装されているオブジェクト指向言語の機能を整理する。クラス型のオブジェクト指向における継承では、ある親クラスを継承した子クラスは親クラスのメソッドやプロパティなどのメンバを再利用出来る。それだけではなく、子クラスの型は親クラスの型としてもみなせる。$fuga);オブジェクト指向言語のなかには、複数の親クラスを継承できる言語もあるがPHPはそうではない。従ってクラスを使ってSingletonパターンをモジュール化しようとしても、何か親クラスを持っているクラスはこれを使うことができない。クラスの継承は、多くのケースで十分に強力だがその一方で不便なケースも存在する。このクラスはすでにFugaクラスを継承しており、上のSingletonクラスを継承できない...}インターフェイスでは、そのインターフェイスに定義されているメソッドを実装クラスがその役割どおり実装することで、その実装クラスの型をインターフェイスの型としてみなすことが出来る。クラスはインターフェイスをいくつも実装できる。true「継承」では親クラスのメソッドやプロパティなどのメンバを再利用でき、かつ親クラスと同じ型として見なせる。それに対して「インターフェイスの実装」では、実装したインターフェイスとクラスを同じ型として見なせる。一つのクラスは複数のインターフェイスを実装できる。「継承」と「インターフェイスの実装」が違うのは、インターフェイスが持っているのはメソッドのシグネチャのみなのでそこにコードの再利用はない点だ。falsetraitはインターフェイスの様にクラスからいくつでも利用できるが、traitは型を持たない。従ってクラスの型に影響を与えない。ここまでの話を簡単に表にまとめると以下のようになる。継承は、親クラスのコードを再利用し、型に関しても親クラスの型として見なせる。クラスが継承できるのはひとつのクラスだけである。インターフェイスは、メソッドの中身を持たないのでコードの再利用はないが、クラスにいくつも型を結びつけられる。traitは、クラスの型になんの影響も与えないが、メソッドとプロパティの集合をクラスの中にいくつも取り込むことが出来る。alpha1から新しく登場したtraitの基本的な概念について説明した。次は、traitのメソッドの衝突とそれの解決について書く。以下のように、利用する複数のtraitでメソッド名が重複した場合、クラスの宣言時にエラーを出す。これをメソッドの衝突と呼ぶ。error!}メソッドの衝突を解決するには、新しく導入された"insteadof"キーワードを用いて優先度を設定する。"hoge"と表示される衝突するメソッドの両方を利用したい場合は、"as"キーワードを用いてエイリアスを設定してメソッドの衝突を解決する。"hoge"と表示される勘違いしやすいが、"as"キーワードを用いたメソッドのエイリアス設定は、メソッド名の変更ではないので注意する。以下のような例を見るとそれがわかる。"hoge"と表示されるメソッド名の変更ではなくメソッド名のエイリアスが作成できる理由は、あるtraitのメソッド内で同じtraitのメソッドを呼び出している場合に、うかつにメソッド名を変えられるとコードが破壊されてしまうようなことを防ぐためと考えられる。メソッドの衝突を解決した際にもtrait本来の振る舞いが破壊されないように考えられていることが以下の例を見るとわかる。"hogehoge"と表示されるこういった例を見ると、新たに登場したtraitがメソッドの衝突の回避やそれを単純に回避した際に起こる問題にもきちんと考えられているのがわかる。alpha1で登場したtraitについてひと通り記述した。traitを触ってみた感想としては、traitを導入した際に付いてくる問題を解決する方法が予め用意されており、考えなしに実装されたアドホックな機能ではないという印象を受けた。PHP5.4正式リリースが楽しみだと思った。Stefan-Marr.dehttp://svn.php.net/viewvc/php/php-src/branches/PHP_5_4/Zend/tests/traits/追記(7/9)この記事中で、メソッドの衝突を解決するのにinsteadofを使わずにasのみを用いているサンプルコードがありましたが、それは間違いですので修正しました。指摘してくださったid:sumimさんありがとうございます。»はてなブログをはじめよう!anatooさんは、はてなブログを使っています。ブログを報告する引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。