オープンソースのWeb開発向けスクリプト言語「PHP」の文法を一から学ぶための入門連載。前回からPHPの「オブジェクト指向言語」としての書き方を紹介しています。今回は、PHPのアクセス修飾子、アクセサメソッド、カプセル化、コンストラクタなどについて。
オープンソースのWeb開発向けスクリプト言語「PHP」の文法を一から学ぶための入門連載「Web業界で働くためのPHP入門」。今回も、前回の続きで、PHPのオブジェクト指向言語としての書き方を紹介します。
今回は、アクセス修飾子、アクセサメソッド、コンストラクタを扱います。
2017年11月30日にPHPの新系列である7.2が正式リリースされました。
PHPサイトの新着ニュースとしてこちらのページで発表されています。また、新機能としてどういったものがあるのかはこちらのページにまとめられています。
ちょうど前回からテーマにしているオブジェクト指向構文については、「インスタンスを格納した変数の型をまとめてobject型として扱える」ことや、「抽象メソッドのオーバーライド」(*)、「データベースとのやりとりを扱うPDO(PHP Data Object)クラスの機能拡張」など、注目に値するものがあります。
*)抽象メソッド、オーバーライドに関しては、この連載中に解説します。
なお、本連載は7.1系列で解説していますが、上記ページの内容を見る限り、サンプルコードは7.2でも動作可能です。
前回の解説で、クラスの作り方、使い方を一通り学んだことになります。今回は、その続きから始めましょう。
前回の最後に作成したリスト6のTestScoreWithMethodクラスで、処理部分をメソッドとしてクラスに含めたとはいえ、リスト7の実行処理部分(useTestScoreWithMethod.php)は相変わらずスッキリしません。
これをもう少しコンパクトに記述できるように、クラス側を改良しましょう。さらに、現状、数英国の合計と平均を表示しているだけの処理をもう少し拡張し、「たろうさん」と「はなこさん」の合計の平均、平均の平均も表示しましょう。そのためには、それぞれの合計値と平均値を取得するメソッドが必要になります。
そのように改良したTestScoreAdvクラスを作成してみましょう。
<?php class TestScoreAdv { //名前プロパティ。 public $name = ""; //数学点数プロパティ。 public $math = 0; //英語点数プロパティ。 public $english = 0; //国語点数プロパティ。 public $japanese = 0; //全データを受け取ってプロパティに格納するメソッド。 public function setData(string $name, int $math, int $english, int $japanese): void *【1】* { $this->name = $name; $this->math = $math; $this->english = $english; $this->japanese = $japanese; } //合計点を計算するメソッド。 public function calcSum(): int *【2】* { $sum = $this->math + $this->english + $this->japanese; return $sum; } //平均点を計算するメソッド。 public function calcAve(): float *【3】* { $sum = $this->calcSum(); $ave = $sum / 3; return $ave; } //名前、合計、平均を表示するメソッド。 public function printScore(): void *【4】* { $sum = $this->calcSum(); $ave = $this->calcAve(); print($this->name."さんの合計: ".$sum." 平均: ".$ave."<br>"); } }
メソッドが4個に増えました。当然ですが、このように1つのクラスに複数のメソッドを記述しても全く問題ありません。それぞれのメソッドの内容は下記の通りです。
プロパティのデータをまとめて受け取れるメソッドです。
TestScoreやTestScoreWithMethodではプロパティそれぞれに実行部分で値を代入する必要がありました。それをまとめて行うメソッドです。そのため、プロパティと同一個数、同一内容の引数を記述し、メソッド内では引数の内容をプロパティに格納する処理を記述しています。
合計値を計算するメソッドです。
メソッドは基本的に関数と同様の記述方法をとるので、このメソッドのように戻り値が必要なものは、メソッドの末尾にreturnを記述し値を返却します。ここではプロパティの3教科の点数を足し算し、その結果を返しています。
平均値を計算するメソッドです。
平均値は、当たり前ですが合計値を個数で割った値です。ということは事前に合計値を計算しておく必要があります。このメソッド内部でプロパティの足し算を行ってもいいのですが、せっかく合計値を計算するメソッドを別に用意しているので、それを呼び出して使います。それが32行目です。プロパティ同様に自分自身のメソッドを呼び出すのにも、「$this」を使います。
またcalcSum()同様、戻り値が必要なので、メソッド末尾にreturnを記述しています。
TestScoreWithMethodクラス同様に合計値と平均値を表示するメソッドです。
TestScoreWithMethodクラスとの違いは、表示する合計値と平均値をこのメソッド内で計算するのではなく、calcSum()とcalcAve()を呼び出してその値を利用していることです。
クラス側が記述できたので、このTestScoreAdvを利用するuseTestScoreAdv.phpを記述し、実行しましょう。
<?php require_once("TestScoreAdv.php"); //たろうさん用のTestScoreAdvを使って、データ表示。 $taro = new TestScoreAdv(); $taro->setData("たろう", 87, 92, 74); $taro->printScore(); //はなこさん用のTestScoreAdvを使って、データ表示。 $hanako = new TestScoreAdv(); $hanako->setData("はなこ", 95, 79, 83); $hanako->printScore(); //たろうさんの合計点を取得。 $taroSum = $taro->calcSum(); //はなこさんの合計点を取得。 $hanakoSum = $hanako->calcSum(); //2人の合計の平均点を計算し、表示。 $ave2 = ($taroSum + $hanakoSum) / 2; print("2人の合計の平均: ".$ave2); //たろうさんの平均点を取得。 $taroAve = $taro->calcAve(); //はなこさんの平均点を取得。 $hanakoAve = $hanako->calcAve(); //2人の平均の平均点を計算し、表示。 $aveAve = ($taroAve + $hanakoAve) / 2; print("<br>2人の平均の平均: ".$aveAve);
実行結果は下記の通りです。
たろうさんの合計: 253 平均: 84.333333333333 はなこさんの合計: 257 平均: 85.666666666667 2人の合計の平均: 255 2人の平均の平均: 85
いかがでしょうか。$taroを生成してからprintScore()までがはるかにコンパクトになりました。$hanakoに関しても同じです。
さらに、例えばたろうさんなら、6行目で$taroに一度データをセットしておくだけで、7行目で表示したり、15行目で合計値を取得したり、22行目で平均値を取得したりすることができます。メソッドさえ作成しておけばデータの取り出しは自由自在です。
これが関数の場合だと、下記のようにその都度引数でデータを渡す必要があります。
$taroSum = calcSum($math, …);
このようにクラスを利用した「オブジェクト指向プログラミング」は、データと処理がワンセットとなっているため、さまざまな利点があります。
Copyright © ITmedia, Inc. All Rights Reserved.