はじめに
PHPの上級試験では、トレイト(Trait)に関する出題が頻出です。
しかし「クラスに似ているのにインスタンス化できない」という特性から、誤解してしまう受験者も少なくありません。
この記事では、
- 試験でありがちな誤答パターン
- 抽象クラス/インターフェイスとの違い
- 身近な料理の例えとASCIIアート図解
を使って、トレイトをしっかり整理します。
目次
トレイトとは?
- 再利用可能なメソッドの部品
- クラスに
use
して埋め込む - インスタンス化はできない
実行例
trait HogeTrait {
public function func() {
echo __METHOD__ , "\n";
}
}
class Hoge {
use HogeTrait;
}
echo "call class \n";
(new Hoge())->func(); // OK
echo "call trait \n";
(new HogeTrait())->func(); // エラー!
実行結果:
call class
HogeTrait::func
call trait
Fatal error: Cannot instantiate trait HogeTrait
試験の誤答パターンとの比較
判定 | コード例 | 挙動 | ポイント |
---|---|---|---|
❌ 誤答 | (new HogeTrait())->func(); | Fatal error | トレイトはインスタンス化できない |
✅ 正答 | (new Hoge())->func(); | HogeTrait::func | クラスに use して初めて利用できる |
👉 「トレイト=クラスっぽいもの」と誤解すると落とし穴にハマります。
抽象クラス・インターフェイスとの違い(例え話)
- クラス … 完成した料理のレシピ
- 抽象クラス … 「スープの基本レシピ(出汁だけ書いてある)」→ 継承して肉付けが必要
- インターフェイス … 「お店のルール表(料理は必ず名前と価格を持つこと)」
- トレイト … 「調理小技カード(みじん切り・ログ出力)」→ どの料理にも混ぜ込み可能
ASCIIアートで整理
+--------------------+ +---------------------+
| Interface | | Abstract Class |
| (ルールブック) | | (未完成の基本レシピ) |
| - 必ず実装すべき関数名 | | - 部分的な処理だけ定義 |
| - 実装は書けない | | - newできない |
+--------------------+ +---------------------+
| |
| implements | extends
v v
+----------------------------------------------------+
| Class |
| (完成した料理のレシピ) |
| - implements ルールブック |
| - extends 基本レシピを肉付け |
| - use 小技カード |
+----------------------------------------------------+
^
| use
|
+--------------------+
| Trait |
| (調理小技カード) |
| - log() |
| - validate() |
+--------------------+
まとめ
- トレイトは 「インスタンス化できない再利用部品」
- クラスに
use
して使う - 抽象クラスやインターフェイスとは役割が違う
- 試験では「トレイトをnewできる」と誤解するミスに注意!