【PHP】トレイト(trait) - クラスコードの再利用
PHPにはトレイトと呼ぶ仕組みがあります。
トレイトはクラスのコードを再利用するために使用します。
ここでは、トレイトについて解説します。
検証環境
トレイト
トレイトは“クラスのコードを再利用する仕組み”です。
フィールドやメソッドを定義し、トレイトを利用宣言したクラスはそれらを使うことができます。
継承と似ていますが、トレイトは“コードの再利用”を目的としており、オブジェクトを表現するものではありません。
トレイトの定義
トレイトを使うには定義が必要です。
基本構文
trait トレイト名 {
// クラス変数・クラスメソッド
// フィールド・メソッド etc...
}
基本的にはクラスの構文と同じですが、class
の部分をtrait
にします。
また、クラスとは異なり、クラス変数は定義できません。
サンプル
// コミュニケーショントレイト
trait Communication {
// メッセージ
private $message;
// あいさつ
public function greeting() {
echo $this->message . "\n";
}
}
$ php sample.php
$
4〜11行目がCommunication
トレイトの定義です。
このトレイトは$message
フィールドとgreeting
メソッドを持ちます。
トレイトの利用
トレイトを利用するにはクラスで利用することを宣言します。
利用するクラスはトレイトのprivate
なプロパティ(フィールドやメソッド等)でも、クラスの定義とみなされるため、正常にアクセスできます。
基本構文
class クラス名 {
___ih_hl_start
use トレイト名1, トレイト名2, ...;
___ih_hl_end
}
クラス内でuse
キーワードに続いてトレイト名を記述します。
複数トレイトを利用する場合は、カンマ(,
)区切りで指定できます。
サンプル
<?php
// コミュニケーショントレイト
trait Communication {
// メッセージ
private $message;
// あいさつ
public function greeting() {
echo $this->message . "\n";
}
}
// 人間クラス
class Person {
// 利用トレイト
___ih_hl_start
use Communication;
___ih_hl_end
// 名前
public $name;
// コンストラクタ
public function __construct( $name, $message ) {
$this->name = $name;
___ih_hl_start
$this->message = $message;
___ih_hl_end
}
// 自己紹介
public function introduction() {
___ih_hl_start
$this->greeting();
___ih_hl_end
echo "My name is " . $this->name . ".\n";
}
}
$person = new Person('TANAKA', 'Hello.');
$person->introduction();
?>
$ php sample.php
Hello.
My name is TANAKA.
20行目でCommunication
トレイトをPerson
クラスで利用することを宣言しています。
そのため、28行目や33行目のように$message
フィールドやgreeting
メソッドを使うことが可能です。
また、アクセス修飾子がprivate
なプロパティへのアクセスも、問題なく処理されたことが分かります。
トレイトの組み合わせ
トレイトで他のトレイトを利用することができます。
利用するにはクラスと同様にuse
キーワードを使用します。
<?php
// コミュニケーショントレイト
trait Communication {
// メッセージ
private $message;
// あいさつ
public function greeting() {
echo $this->message . "\n";
}
}
// 基本行動
trait BaseAction {
// 利用トレイト
___ih_hl_start
use Communication;
___ih_hl_end
// 食事
public function meal() {
echo "Eating...\n";
}
}
// 人間クラス
class Person {
// 利用トレイト
use BaseAction;
// 名前
public $name;
// コンストラクタ
public function __construct( $name, $message ) {
$this->name = $name;
$this->message = $message;
}
// 自己紹介
public function introduction() {
$this->greeting();
echo "My name is " . $this->name . ".\n";
}
}
$person = new Person('TANAKA', 'Hello.');
$person->introduction();
$person->meal();
?>
こんにちは!
Hello.
My name is TANAKA.
Eating...
20行目でBaseAction
トレイトがCommunication
トレイトを使うように宣言しています。
Person
クラスはBaseAction
トレイトを利用しており、各トレイトのプロパティに問題なくアクセスできます。
演習問題
次の実行結果になるプログラムを作成してください。
なお、下記条件を満たすものとします。
- 次の表のクラス・トレイトを作成する
- 人間クラス、コンピュータークラスのインスタンスからaddメソッドを実行する
種類 | 名称 | 英記 | トレイト | メソッド |
---|---|---|---|---|
トレイト | 計算トレイト | Calculation | – | ・add( $x, $y )
→ 2値の足し算を出力する |
具象クラス | 人間クラス | Person | Calculation | – |
具象クラス | コンピュータークラス | Computer | Calculation | – |
=== Person ===
123 + 456 = 579
=== Computer ===
12345 + 67890 = 80235
次の実行結果になるプログラムを作成してください。
なお、下記条件を満たすものとします。
- 次の表のクラス・トレイトを作成する
- 人間クラスのインスタンスからトレイトで定義したメソッドを全て呼び出す
- 猫クラスのインスタンスからトレイトで定義したメソッドを全て呼び出す
種類 | 名称 | 英記 | 継承 | トレイト | フィールド | メソッド |
---|---|---|---|---|---|---|
トレイト | コミュニケーショントレイト | Communication | – | – | – | ・greeting()
→ 『こんにちは』を出力する。 ・ introduction()
→ 『私の名前は●●です』を出力する ※ 『●●』は$nameフィールドの値 |
トレイト | 運動トレイト | Motion | – | – | – | ・run()
→ 『走る』を出力する ・ jump()
→ 『ジャンプ』を出力する |
抽象クラス | 生物クラス | Creature | – | – | $name | ・コンストラクタ
→ $nameの値を初期化 |
具象クラス | 人間クラス | Person | Creature | Communication
Motion |
– | – |
具象クラス | 猫クラス | Cat | Creature | Motion | – | – |
=== Person ===
こんにちは
私の名前はWatanabe Youです。
走る
ジャンプ
=== Cat ===
走る
ジャンプ