大規模PHP開発で欠かせないアクセス修飾子とカプセル化、アクセサー、コンストラクター/デストラクター:PHPオブジェクト指向プログラミング入門(2)(3/3 ページ)
「PHPで、どのようにオブジェクト指向プログラミングをしていくか」を解説する連載。今回は、アクセス修飾子、カプセル化と隠蔽(いんぺい)、アクセサー、コンストラクター/デストラクターについて解説し、最後に「再代入の是非」について触れます。
コンストラクター/デストラクター
インスタンスが作成されるときに自動的に走るメソッドとして「コンストラクター」というメソッドが、多くの言語に存在します。PHPにも、この「コンストラクター」が存在します。
まずは実際にコードを書いて、コンストラクターの存在を確認してみます。
<?php class hoge { public function __construct() { echo "run constructor\n"; } } // $obj = new hoge();
__constructメソッドは、明示的には呼ばれていません。しかし「newされたタイミング」で自動で呼び出されます。その証左として、上述プログラムを動かすと「__constructメソッドをcallしていないのに、__constructメソッドが呼ばれている」様子が分かるかと思います。
また、コンストラクターと対になる概念として「デストラクター」というメソッドがあります。デストラクターは言語によってあったりなかったりしますが(典型的には、Javaが「デストラクターのない」言語です)、PHPではデストラクターが存在します。
デストラクターは「インスタンスが消去されるタイミング」で自動で呼び出されます。「消去されるタイミング」という状況を厳密に定義するのは少し難しいのですが、取りあえず「プログラム終了時」「変数のスコープが外れる」「インスタンスが入っている変数に別の値が代入される(典型的にはnullなどが代入される)」といったタイミングを意識しておくとよいでしょう。
上述した三つのパターンのサンプルプログラムをそれぞれ書いて、デストラクターの存在、およびデストラクターが走るタイミングを確認してみます。
<?php class hoge { public function __destruct() { echo "run destructor\n"; } } // プログラム終了時にデストラクターが走る $obj = new hoge();
<?php class hoge { public function __destruct() { echo "run destructor\n"; } } // function f() { $obj = new hoge(); } // 変数のスコープが外れる f(); sleep(5); // 「プログラム終了時にデストラクターが走る」と区別するためのsleep
<?php class hoge { public function __destruct() { echo "run destructor\n"; } } // インスタンスが入っている変数に別の値が代入される $obj = new hoge(); $obj = null; sleep(5); // 「プログラム終了時にデストラクターが走る」と区別するためのsleep
コンストラクターは、よく「インスタンスの初期化」などに用いられます。引数などで外部からデータを渡すことも可能です。エラーをreturnで返すことはできないので、「コンストラクターの処理でエラーになった」場合は、例外を投げる必要があります。
デストラクターはあまり使われることがありませんが、主として「コンストラクターで確保したリソースの解放」などに用いられることが多いです。そういった意味合いでも「コンストラクターと対になる」ことが多いと言えます。
イミュータブル(immutable)なオブジェクトについての一考
変数において「再代入の是非」というのが今でも議論されています。「再代入」というのは簡単に書くと「一度変数に何か値をいれた後で、別の値を上書きする」ことです。
<?php $i = 10; var_dump($i); $i = 20; // ここで変数$iに、値を再代入 var_dump($i);
こういった「再代入」は、関数型言語、と呼ばれる言語の世界観では「できない(あるいは好ましくない)」とされています。
この「再代入の禁止」というのは、手続き型言語の一つであるPHPを「普通に」学んでいると、「全面的に取り入れる」のは難しいと思いますが、クラスの設計によっては「一度入れられた値を変える必要がない(または変えるとバグが発生しやすくなる)」もの、ということがあり得ます。
そういったときに「コンストラクターで値を設定、その後に値を変えることができない」クラス、というパターンが有効な場合があり、それを「イミュータブルなオブジェクト(不変オブジェクト)」という言い方をします。
実装例を書いてみましょう。
<?php class hoge { public function __construct($v) { $this->_val = $v; } public function getVal() { return $this->_val; } // private $_val; } // $obj = new hoge('vall'); var_dump( $obj->getVal() );
イミュータブルなオブジェクトでは、コンストラクターでデータを決定させます。また、setterは作成しません。プロパティはもちろんprivateになります。
イミュータブルなインスタンスは「再代入がない」ので、結果的に「そのインスタンスがどんな情報を持っているか」が明示的であり、「プログラムの流れによってインスタンスの状態が遷移する可能性がない」と言えます。
また、その状況は結果的に「デバッグの容易性」「テストパターンの減少」など、いくつかのメリットを生じさせます。本連載のメインターゲットである「初級本を読み終わった/PHP 5技術者認定初級試験には合格した」くらいの人だと、まだ少し難しい概念ですが、今は「そんなものもあるんだ」といった程度に覚えておいてください。
こういったさまざまな概念を状況に合わせて使いこなせるようになると、プログラミングの腕前が上がって、より良いコードが書けるようになります。
次回は「継承」について
次回は、オブジェクト指向プログラミングの中でも一つ大きなポイントになる「継承」について、書き方と考え方の両方向から解説していきます。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- 初心者がPHPプログラミングを始めるための基礎知識とXAMPPのインストール
オープンソースのWeb開発向けスクリプト言語「PHP」の文法を一から学ぶための入門連載。初回は、PHPの概要や特徴を紹介し、環境構築や「Hello World!」までの手順などを解説します【PHP 7.1含め2017年の情報に合うように対応、XAMPP環境構築を追記】。 - PHP編に突入! まずはソースをダウンロード
今回からPHPのビルドとインストールに入ります。まずはPHPという言語の概要と、ソースコードの入手法を解説します(編集部) - 理論編:PHPについて知ろう
スクリプトを記述するだけの簡単なプログラミングで、Web対応の高速なデータベースアプリケーションを実現する手法としてPHPが急速に注目を集めている。しかもデータベースはオープンソースのPostgreSQLだけでなく、Oracleなどの商用データベースも扱える。ここでは、5月にバージョンアップしたばかりのPHP4によるWeb-DBシステム構築法を紹介しよう。 - Mac OS X+PHPでオールインワン環境(インストール編):Mac内にPHP4、5、6を同居させるコツ
PHP4の開発は終了したが、移行の問題は残されている。異なるバージョンのPHPをスムーズに切り替えるには? - @IT自分戦略研究所 資格辞典:PHP技術者認定試験
- 自分をプログラミング言語に例えると何?
2013年1月16日、エンジニアたちが集うトークライブイベント「TechLION vol.11」が開催された。今回のレポートでは、「自分をプログラミング言語に例える」というお題に答えた5人の技術者の回答をみていく。