Javaのせいで難しいとレッテルを貼られてしまったクラスですが、さほど難しいものではありません。
ただ単に、幾つかの関数を纏めて一塊にしてみました、それだけのことです。
特にPHPのクラスは実のところ連想配列そのものです。
継承など面倒な概念も幾つかありますが、まあそれはおいおい。
ちなみに以下はPHP4での話です。
PHP5でも基本は同じだと思いますが、よりオブジェクト指向的な書き方ができるようになっています。
さて、さっそくクラスを作ってみましょう。
作り方は簡単です。
関数を作る要領で、functionのかわりにclassで全体を囲むだけです。
また、クラスの外部から操作を行うためのメソッドというものを書く必要がありますが、こちらは関数そのものです。
まあとりあえず作ってみましょう。
class Animal{ //名前を決めるメソッド //名前を取得するメソッド |
クラスを初めて触ったときに一番わかりにくい概念が、インスタンス化だと思います。
クラスは関数のように書いただけでは使用することができず、インスタンス化という儀式を通さないといけません。
$AnimalA = new Animal;
こうすることでAnimalクラスが$AnimalAという名前で実体化されました。
以降は$AnimalAという実体化されたクラスに対して操作を行うことができます。
Animalクラスの中のsetName関数に触ってみましょう。
$AnimalA->setName("dog");
クラスとクラス内関数や変数との繋ぎは「->」で表します。
さて、上の関数でどうなったかというと、クラス内の変数$aNameに、setName関数で与えた引数"dog"が設定されました。
同様に、
$AnimalA->getName();
という関数を実行すると$AnimalAクラス内の変数$aName、すなわち先ほど設定した"dog"が返ってきます、
以後クラス内の変数には、直接触るのではなく、常に関数を通じてアクセスすることになります。
今度はもうすこし複雑なクラスを作ってみます。
class Circle{ var $radius; //半径をセット //面積を取得 |
pow($this->radius,2)*M_PIは半径から面積を計算しています。
M_PIは円周率を表す定数(=3.14159265358979323846)、pow(a,b)はaのb乗です。
関数の恐ろしく豊富なPHPですが、何故か^は使えません(何故かxorにアサインされている)
$circle1=new Circle;
とすることで$circle1をCircleクラスとして扱うことができるようになります。
$a->setRadius("3");
で半径3をセットし、
$a->getArea();
で先ほどセットした半径から計算した円の面積を取得することができます。
さてコンストラクタという見慣れぬ名前の関数があります。
クラス名と同名の関数は、クラスのインスタンス化と同時に実行される、という特徴があります。
この場合、$circle1=new Circle;と書いた時点で自動的にfunction Circleも実行されるのです。
Circle関数が何をやってるかというと、引数を半径にセットしています。
つまり、
$circle2=new Circle(3);
と書けば最初から半径に3がセットされるというわけです。
コンストラクタは主に変数の初期化等に使われます。
クラスを使って何が便利かというと、同じ定義を使いまわせることです。
例えばAnimalクラスは以下の連想配列とほぼ同義です。
$AnimalA=array("aName",$name);
しかし、同じ定義の連想配列を他で使用したくなった場合も再度同じことを書かなければなりません。
$AnimalB=array("aName",$name);
クラスならば最初に定義してしまえば、何度でも使いまわすことができます。
$AnimalA = new Animal;
$AnimalB = new Animal;
この場合は中身がひとつだけなのでたいして変わりませんが、キーが何十個もあるような複雑な連想配列を考えてみるとクラスの便利さがわかるでしょう。
同じ処理は関数に纏めましょう、というのと同じように、同じオブジェクトはクラスに纏めましょう、ということです。
さて、PHPのクラスはほぼ連想配列なので、何気に連想配列的な操作を行うことができます。
例えば$AnimalA->aName="dog";と書くと、メソッドを介さずに直接変数をセットできてしまいます。
同様にprint_r($AnimalA);と書いてしまうとクラス変数の中身が全部表示されてしまいます。
それどころか$AnimalA->aBark="wanwan";などと元のクラスに存在しないプロパティを作成できてしまったりとやりたい放題です。
オブジェクト指向としては非常に正しくない実装なので大問題です。
PHP5ではprivateなどのアクセス権を設定できるようになっており、上記の問題点は改善されつつあります。
さて次回はクラスの継承についてと言いたいのだが、そこまでやったところで個人レベルじゃどうせ使わないんだよなあ継承。
継承すればするほどオブジェクト指向の目的から外れていくと思うのは私だけでしょうか。