PHPにおける継承とextends、オーバーライドとparent、final、protected:Web業界で働くためのPHP入門(17)(2/3 ページ)
オープンソースのWeb開発向けスクリプト言語「PHP」の文法を一から学ぶための入門連載。今回は、クラスを拡張する方法として、継承を扱います。
オーバーライドとparent
継承の基本が理解できたところで応用していきます。
親クラスのメソッドを上書きするオーバーライド
継承では、親クラスのメソッドを上書きすることができます。どういった処理なのかをサンプルで見ていきましょう。
まず、親クラスに当たる以下のGoodsクラスを作成してください。
<?php class Goods { //商品名プロパティ private $name = ""; //商品価格プロパティ private $price = 0; //コンストラクタ。商品名と商品価格を設定する public function __construct(string $name, int $price) { $this->name = $name; $this->price = $price; } //商品名と価格を表示するメソッド public function printPrice(): void { print($this->name."の価格: ¥".$this->price."<br>"); } //商品名のゲッタ public function getName(): string { return $this->name; } //商品価格のゲッタ public function getPrice(): int { return $this->price; } }
コメントにある通り、商品名と価格のプロパティ、それらに値を設定するコンストラクタとそれぞれのゲッタ、さらに、商品名と価格を表示するメソッドから構成されたクラスです。
次に、このクラスを継承した子クラスとして、以下のGoodsWithTaxクラスを作成してください。
<?php class GoodsWithTax extends Goods { //商品名と価格を表示するメソッド。税込みで表示するように変更 public function printPrice(): void { //商品価格の税込み価格を計算し、表示 $priceWithTax = round($this->getPrice() * 1.08); // (1) print($this->getName()."の税込み価格: ¥".$priceWithTax."<br>"); // (2) } }
メソッドが1つだけ定義されたクラスです。メソッド内の処理は、親クラスで定義されたゲッタを使って商品価格を取得し、それを1.08倍することで税込み価格を計算しています。その際、round()関数を使って丸め処理も行っています(1)。さらに、その税込み価格を表示しています(2)。
ただ、そのメソッドをよく見ると、親クラスであるGoodsにも同名のprintPrice()メソッドが存在します。これは、親クラスのprintPrice()メソッドを上書きしていることになります。このように親クラスの同名メソッドを子クラスで定義し直すことを「オーバーライド」といいます(図2)。
オーバーライドされたメソッドの挙動
オーバーライドされたメソッドを呼び出すとどのような挙動になるのでしょうか。リスト4のGoodsクラスとリスト5のGoodsWithTaxクラスを利用するサンプルで見ていくことにしましょう。以下のuseGoods.phpを作成し、実行してください。
<?php require_once("Goods.php"); require_once("GoodsWithTax.php"); $goods = new Goods("ハンドクリーム", 350); // (1) $goods->printPrice(); // (2) $goodsWithTax = new GoodsWithTax("日焼け止め", 500); // (3) $goodsWithTax->printPrice(); // (4)
実行結果は以下の通りです。
ハンドクリームの価格: ¥350 日焼け止めの価格: ¥540
リスト6では、まず親クラスであるGoodsと子クラスであるGoodsWithTaxをそれぞれnewしています((1)と(3))。その際、プロパティにセットするデータを引数として渡しています。そして、それぞれのprintPrice()メソッドを実行しています。
(2)ではGoodsインスタンスのprintPrice()メソッドを実行し、それが実行結果の1行目です。表示された価格が設定した価格そのままなので、GoodsクラスのprintPrice()メソッドが実行されたのが分かります。
一方、(4)ではGoodsWithTaxインスタンスのprintPrice()メソッドを実行し、それが実行結果の2行目です。表示された価格が税込み価格なので、GoodsWithTaxクラスのprintPrice()メソッドが実行されたのが分かります。
このように、オーバーライドされたメソッドでは、親クラスに記述されたコードは無視されて、子クラスのコードをそのまま実行することになります。
コンストラクタの扱い
ところで、リスト6の(3)に注目してください。ここでは、new時に引数として「日焼け止め」「500」という値を渡しています。ということは、コンストラクタが実行されていることになりますが、そのコンストラクタがGoodsWithTaxクラスには記述されていません。ここで実行されているコンストラクタは親クラスであるGoodsクラスに記述されているものを使っています。このように、PHPではコンストラクタも通常のメソッドと同様に子クラスから利用できます。
また、オーバーライドも可能です。子クラスで独自のコンストラクタを記述することで、そのコンストラクタが実行されます。
親クラスのコードも実行するparent
では、オーバーライドされたメソッドで、親クラスのコードも実行したい場合は、方法はないのでしょうか? これは、可能です。サンプルで見ていきましょう。
Goodsクラスを継承した以下のGoodsWithTax2クラスを作成してください。なお、ソースコードの内容は、リスト5のGoodsWithTaxクラスとほぼ同じです。違いは、クラス名と新たに追記した(1)の1行だけです。
<?php class GoodsWithTax2 extends Goods { //商品名と価格を表示するメソッド。税込みで表示するように変更 public function printPrice(): void { //親クラスの同名メソッドの呼び出し parent::printPrice(); // (1) //商品価格の税込み価格を計算し、表示 $priceWithTax = round($this->getPrice() * 1.08); print($this->getName()."の税込み価格: ¥".$priceWithTax."<br>"); } }
ここでのポイントはリスト7の(1)で登場した「parent::」です。オーバーライドしたメソッド内で、親クラスの同名メソッドを呼び出すには、この記述を使います。構文としてまとめると以下のようになります。
構文 オーバーライドした親クラスの呼び出し
parent::同名メソッド
実際に親クラスのメソッドが実行されるかを確かめてみましょう。このクラスを利用する以下のuseGoods2.phpを作成し、実行してください。
<?php require_once("Goods.php"); require_once("GoodsWithTax2.php"); $goods = new GoodsWithTax2("リップクリーム", 200); $goods->printPrice(); // (1)
実行結果は以下の通りです。
リップクリームの価格: ¥200 リップクリームの税込み価格: ¥216
(1)でGoodsWithTax2インスタンスのprintPrice()メソッドを実行しています。実行結果から、明らかに親クラスの同名メソッドも実行されていることが読み取れます。
親コンストラクタの呼び出し
この「parent::」は親コンストラクタの呼び出しにも使います。子クラスでコンストラクタをオーバーライドし、その子クラスのコンストラクタ内で親クラスのコンストラクタを呼び出したい場合は、以下のように記述します。
public function __construct(……) { parent::__construct(); : : }
注意!!「final」
オーバーライドの話が出てきたところで、1つ補足しておきます。
メソッドによっては、子クラスでオーバーライドされたくない場合というのもあり得ます。その場合は、以下のようにメソッド定義に「final」を付けます。
final public function doSomething() {……}
同様に、継承不可のクラス、つまり子クラスが作成できないクラスを定義したい場合は、以下のように「final」をクラス宣言に付けます。
final class Base {……}
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- WordPress活用に欠かせない、PHPをWindowsにダウンロードしてインストール、アンインストールする
本連載では、さまざまなソフトウェアのインストール、実行するためのセットアップ設定、実行確認、アンインストールの手順を解説する。今回は、PHPとは何か、PHPで動くツールの紹介、PHPのインストールとアンインストールについて解説。PHPプログラミングを始める参考にしてほしい。 - PHPにおけるクラスの書き方と呼び出し方――インスタンス、メソッド、プロパティ
「PHPで、どのようにオブジェクト指向プログラミングをしていくか」を解説する連載。初回は、「クラス」の書き方と簡単な使い方、メソッド/クラス定義内関数、プロパティ/クラス定義内変数、マルチプルインスタンスについて紹介します。 - PHP(スクリプト言語)
PHPは、HTMLへの埋め込みが可能なスクリプト言語(およびその処理系)。主としてWebアプリ開発に使用される。