PHP4からPHP5になって、PHPがJava化しているとか言われますけど、オブジェクト指向が強まったのも理由かもしれません。
CakePHPの勉強をはじめたことですし、PHP5のクラス定義をおさらいする個人メモ。
クラスの利用
<?php
class Hoge {
var $name = '太郎';
function get_name() {
return $this->name;
}
}
// オブジェクトは参照渡し
$a = new Hoge;
$b = $a;
$b->name = '次郎';
echo $a->get_name() . "<br />";
// オブジェクトのコピー
$c = new Hoge;
$d = clone $c;
$d->name = '次郎';
echo $c->get_name();
?>
以下、上記ソースの実行結果。
次郎
太郎
このブログのPHPのバージョンは、PHP5です。
まず、クラスの利用を確認してみると・・・
単にインスタンス化したオブジェクトを、「$b = $a;」と代入すると、参照渡しになっていることを確認できます。
オブジェクトをコピーして別物として扱うには、「$d = clone $c;」とclone演算子を使う。
じゃ、次にクラス定義のほう。
オブジェクト指向は、利用よりもクラス定義のほうがはるかに難しいし、センスが要りますね。
メソッド、プロパティの宣言
static宣言 (スタティックメソッド、スタティックプロパティ)
<?php
class Static_Hoge {
static function get_name() {
return '太郎';
}
}
$a = new Static_Hoge;
echo $a->get_name() . '<br />';
echo Static_Hoge::get_name();
?>
スタティックメソッド(静的メソッド)やスタティックプロパティ(静的プロパティ)は、共通して使うようなメソッド、プロパティをクラス内に定義する場合にstaticで宣言する。
new演算子でオブジェクトを生成しても呼び出せるけど、オブジェクトを生成せず「Static_Hoge::get_name();」と「クラス名::メソッド名」とするだけで呼び出せます。
また、クラス名やメソッド名の頭に、「final」キーワードを付けると、サブクラス(子クラス)での継承、オーバーライドを制限する。
プロパティ、メソッドのアクセス制限
public、private、protectedなどのアクセス修飾子がPHP5から使えるようになっています。
ちょっと簡単なクラスと継承を書いてテスト。
<?php
// アクセス制限テストの親クラス
class Access_Hoge {
public $tarou = '太郎';
private $jirou = '次郎';
protected $kojirou = '小次郎';
}
// 継承クラス
class Child_Access_Hoge extends Access_Hoge {
function tarou() {
// publicはどこからでもアクセス可能
return $this->tarou;
}
function jirou() {
// privateはアクセス不可能
return $this->jirou;
}
function kojirou() {
// protectedは子クラスのメソッドからアクセス可能
return $this->kojirou;
}
}
// オブジェクト生成してアクセスできるか実験
$a = new Access_Hoge;
echo $a->tarou . '<br />';
echo $a->jirou . '<br />'; // $jirouはprivate宣言なのでエラー
echo $a->kojirou . '<br />'; // $kojirouはprotected宣言なのでエラー
// サブクラスで実験
$b = new Child_Access_Hoge;
echo $b->tarou() . '<br />';
echo $b->jirou() . '<br />'; // $jirouは親クラスでprivate宣言なのでエラー
echo $b->kojirou() . '<br />'; // $kojirouは親クラスでprotected宣言なのでアクセスできる
?>
publicの場合、クラス外部・内部のどこからでもアクセス可能です。
privateの場合、それを宣言しているクラス内部からのみアクセス可能、protectedの場合、定義クラスおよびその子クラスからアクセス可能です。
クラス内での定数の定義
あと、クラス定義内でconstを頭につけると、define関数みたいな定数の定義ができる
staticとあわせて、const宣言のプロパティへのアクセスは、以下の通り。
<?php
class Const_Hoge {
const MYNAME = '変なおじさん';
static $myname = 'たけちゃんまん';
}
echo Const_Hoge::MYNAME . '<br>';
echo Const_Hoge::$myname . '<br>';
?>
実行結果。
変なおじさん
たけちゃんまん
interface(インターフェース)とabstract(抽象クラス・抽象メソッド)
<?php
interface Printout {
// メソッド宣言のみで実装しない
public function printOut();
}
class Img_Print implements Printout {
// interfaceで宣言したメソッドの実装
function printOut() {
return '画像を印刷中です';
}
}
?>
まず、interfaceで実装すべきメソッドを宣言だけしておき、実装はしません。
その後、implements(実装)するclassの中で、interfaceで宣言したメソッドを実装する。
こうしておけば、定義する(またはすべき)メソッドをinterface内で一覧確認できる効果があるそうです。
また、interfaceと似ている機能で、abstractという抽象クラス・抽象メソッドを宣言するキーワードもあります。
<?php
abstract class Component {
abstract function printOut();
public function info() {
echo 'コンポーネントです。';
}
}
class ImgComponent extends Component {
function printOut() {
return '高画質の写真を表示';
}
}
?>
こちらは、abstract class と抽象クラスを定義し、その中のメソッドもabstractで定義する。
interfaceと違う点は、抽象クラス(abstract宣言のクラス)の中で、関数の実装も行える点。
コンストラクタとデストラクタ
PHP4までは、コンストラクタはクラス名と同じ名前で宣言していたが、
クラス内で「function __construct」で宣言できるようになった。
これにより、親クラスの名前を何回も書く必要がなくなります。子クラスから親クラスのコンストラクタを呼び出す場合・・・
「parent::_construct()」で呼び出せるので、メンテナンス性が高まります。
デストラクタの宣言も、「function __destruct()」で可能になった。
以上、PHP5のクラス定義とオブジェクトについてでした。
CakePHPのソースを読み解くには、これらの理解がないと無理っぽかったんで復習してみました。
今日の記事を読んで、
Java プログラミングしていた頃が、
懐かしくなりました。
exception のこなし方がうまくなると、
想定外のエラーのデバッグが楽になりますよ。
ですね、Javaだとクラスあってのプログラミングですもんね。
私は最初それがものすごく面倒くさく思えて、Java無理・・・って思いましたよ。
System.out.printlnよりも、echoやprintのほうが簡単に思えたのでPHPやPerlにしました。
でもライブラリ充実しているのは強みですよね。
■この記事のトラックバックURL:
http://www.mapee.jp/mpe334/mt-tb.cgi/141