
【PHP】トレイト(trait) – クラスコードの再利用
PHPにはトレイト(trait)と呼ばれる仕組みがあります。
トレイトはクラスでコードを再利用するために使います。
ここではトレイトについて解説します。
-
トレイト
トレイトとは
トレイトはクラスでコードを再利用する仕組みです。
トレイトはフィールドやメソッドを定義することができ、クラスでトレイトの利用を宣言することで、それらを使うことができます。
継承と似ていますが、トレイトは『コードを再利用する』ことを目的としており、オブジェクトを表現するものではありません。
基本構文
トレイトは定義と利用の基本構文があります。
定義
trait トレイト名 {
// クラス変数・クラスメソッド
// フィールド・メソッド
}
基本的にはクラスの構文と同じですが、class
の部分をtrait
とします。
また、クラス変数やクラスメソッド、フィールド、メソッドを定義することができますが、クラス変数は定義できません。
利用
class クラス名 {
use トレイト名;
}
クラス内でuseキーワードに続いてトレイト名を記述します。
もし、複数のトレイトがある場合は、カンマ(,
)区切りで記述することができます。
サンプルコード
トレイトを使ったサンプルコードをご覧ください。
<?php
trait Communication {
private $text;
public function greeting() {
echo $this->text."\n";
}
}
class Person {
use Communication;
public $name;
public function __construct($name, $text) {
$this->name = $name;
$this->text = $text;
}
public function profile() {
echo "私の名前は".$this->name."です。\n";
}
}
$watanabe = new Person('Watanabe You', "こんにちは!");
$watanabe->greeting();
$watanabe->profile();
?>
こんにちは!
私の名前はWatanabe Youです。
このコードの解説は次の表をご覧ください。
行数 | 概要 |
---|---|
3~11 | Communicationトレイトを定義。 |
13~28 | Personクラスを定義し、Communicationトレイトを使用するよう宣言。 |
30~32 | Personクラスから2つインスタンスを生成し、それぞれでgreetingメソッドとprofileメソッドを呼び出し。 |
PersonクラスでCommunicationトレイトを利用しているため、インスタンスからgreetingメソッドが使えており、コンストラクタで$textへのアクセスができています。
また、トレイトを利用することはトレイトの定義がクラスで定義されていることに等しいため、$textはprivateですが、クラス内の定義とみなされ正常にアクセスできます。
このあたりは継承と違う部分になります。
複数トレイト
1つのクラスに対して複数のトレイトを利用することができます。
上記サンプルコードにCalculationトレイトを追加した次のコードをご覧ください。
<?php
trait Communication {
private $text;
public function greeting() {
echo $this->text."\n";
}
}
trait Calculation {
public function addition( $x, $y ) {
$total = $x + $y;
echo $x." + ".$y." = ".$total."\n";
}
}
class Person {
use Communication, Calculation;
public $name;
public function __construct($name, $text) {
$this->name = $name;
$this->text = $text;
}
public function profile() {
echo "私の名前は".$this->name."です。\n";
}
}
$watanabe = new Person('Watanabe You', "こんにちは!");
$watanabe->greeting();
$watanabe->profile();
$watanabe->addition(3, 5);
?>
こんにちは!
私の名前はWatanabe Youです。
3 + 5 = 8
24行目のように複数のトレイトを使用する場合はカンマ(,
)区切りでトレイトを記述します。
演習問題
次の実行結果になるプログラムを作成してください。
なお、下記条件を満たすものとします。
- 次の表のクラス・トレイトを作成する
- 人間クラス、コンピュータークラスのインスタンスから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 ===
走る
ジャンプ
まとめ
トレイトはクラスのコードを再利用するための仕組みです。
継承とは異なり、クラス自体に定義されたものとみなされるため、privateな定義もクラスから使えるようになります。