クラスを水平方向に拡張できるPHPの「トレイト」:Web業界で働くためのPHP入門(19)(1/3 ページ)
オープンソースのWeb開発向けスクリプト言語「PHP」の文法を一から学ぶための入門連載。今回は、クラスに対して横断的に機能を追加できる「トレイト」について解説します。
オープンソースのWeb開発向けスクリプト言語「PHP」の文法を一から学ぶための入門連載「Web業界で働くためのPHP入門」。
今回は、クラスに対して横断的に機能を追加できる「トレイト」について解説します。
「トレイト」とは
トレイトは、継承とはまた別の方法でクラスを拡張できる仕組みです。最初に少し概論的な話をしておきましょう。
垂直方向にクラスを拡張する継承の問題点
連載第17回でクラスを拡張できる仕組みとして継承を解説しました。その継承は親クラスを文字通り引き継ぎ、そこに子クラス独自のプロパティやメソッドを追加することで拡張します。例えば、スポーツ選手を表すSportsPlayerクラスがあったとします(リスト1)。
<?php class SportsPlayer { //名前のプロパティ。 private $name; //コンストラクタ。名前プロパティに値をセットする。 public function __construct(string $name) { $this->name = $name; } //名前プロパティのゲッタ。 public function getName():string { return $this->name; } }
これを継承したTennisPlayerクラス、HandballPlayerクラス、BaseballPlayerクラスを考えます。それぞれクラス名の通り、「テニス選手」「ハンドボール選手」「野球選手」を表します。それぞれのクラスには、その球技で使う道具、例えばテニスならラケット、野球ならバットとグローブを表すプロパティ(ハンドボールは道具を使いません)と、その球技独特の何かメソッドを追加するとします。
ここで、メソッドとして、その球技の主要な動作を考えます。例えば、テニスならば「打つ」で、ハンドボールならば「投げる」です。野球にはこの両方の動作が含まれます(図1)。
ここで、もう一段階考えます。テニスと野球には同じ動作(=処理)である「打つ」が含まれています。共通の処理がある場合は、それは親クラスに記述した方が継承のメリットを生かせます。そのように考えてSportsPlayerクラスに「打つ」を追加したとします(図2)。
すると、問題が生じます。HandballPlayerクラスにも「打つ」が含まれてしまうことになります。ハンドボールに「打つ」は不要です。同様に、「投げる」を親クラスに追加したら、今度はTennisPlayerクラスに不要な処理が含まれてしまいます。親から子へ、子から孫へと内容を引き継ぐ継承は、縦方向(垂直方向)のクラスの拡張といえますが、垂直方向故に、このような問題が生じます。
クラス横断的に機能を追加できるトレイト
この問題を解決するのが、トレイトです。トレイトは水平方向のクラスの拡張といえます。それは、各クラスにプロパティとメソッドのカタマリを、あたかも機能拡張のように追加できます。例えば、「打つ」というトレイトと「投げる」というトレイトの2個を用意しておき、TennisPlayerクラスには「打つ」トレイトを組み込みます。HandballPlayerクラスには「投げる」トレイトを組み込みます。そして、BaseballPlayerクラスには両方のトレイトを組み込みます(図3)。
トレイトの作成は「trait」宣言
では、実際にソースコードでみていきましょう。まず、「打つ」を表すトレイトであるHitTraitトレイトを作成します。これは、リスト2のようになります。
<?php trait HitTrait // (1) { public function hit():void // (2) { print(__CLASS__."がボールを打ちます。<br>"); // (3) } }
トレイトを作成するには、(1)のように「trait」宣言を使います。トレイト名は、HitTraitのように「○○Trait」とするのが習わしです。
構文「トレイト」
trait ○○Trait
{
プロパティ
メソッド
:
}
トレイトはクラス機能の一部を切り出したものですので、クラス同様にプロパティやメソッドを記述できます。リスト2では「打つ」を表すhit()メソッドを記述しています。それが(2)です。プロパティやメソッドの記述方法はクラスと同じです。
メソッド内の処理は「打つ」を模倣したようなものにするために単に「ボールを打ちます」と表示するようにしました。それが(3)です。ただ、そのときに「どのクラスで、このトレイトが利用されたのか」を明確にするように、主語にクラス名を表示させるようにしています。PHPでは実行中のクラス名を表示するための定数が用意されており、(3)の「__CLASS__」が該当します。
さて、同じように「投げる」を表すThrowTraitトレイトを作成しましょう(リスト3)。
<?php trait ThrowTrait { public function throw():void { print(__CLASS__."がボールを投げます。<br>"); } }
基本構造はHitTraitトレイトと同じです。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- WordPress活用に欠かせない、PHPをWindowsにダウンロードしてインストール、アンインストールする
本連載では、さまざまなソフトウェアのインストール、実行するためのセットアップ設定、実行確認、アンインストールの手順を解説する。今回は、PHPとは何か、PHPで動くツールの紹介、PHPのインストールとアンインストールについて解説。PHPプログラミングを始める参考にしてほしい。 - PHPにおけるクラスの書き方と呼び出し方――インスタンス、メソッド、プロパティ
「PHPで、どのようにオブジェクト指向プログラミングをしていくか」を解説する連載。初回は、「クラス」の書き方と簡単な使い方、メソッド/クラス定義内関数、プロパティ/クラス定義内変数、マルチプルインスタンスについて紹介します。 - PHP(スクリプト言語)
PHPは、HTMLへの埋め込みが可能なスクリプト言語(およびその処理系)。主としてWebアプリ開発に使用される。