トレイトは、継承によって関連していない複数のクラス間でコードを再利用するメカニズムです。PHPは単一継承のみを許可しているため、トレイトはメソッド(とプロパティ)を水平的に共有する方法を提供します。これはmixinのような「合成的な」コード再利用の形式です。
トレイトが解決する問題
PHP has single inheritance — a class can extend only ONE parent. But you often want
to share the SAME methods across unrelated classes (e.g. logging, timestamps).
Duplicating the code is bad; traits let you reuse it without inheritance.
トレイトの定義と使用
<?php
trait Timestampable {
private ?DateTime $createdAt = null;
public function setCreatedAt(): void {
$this->createdAt = new DateTime();
}
public function getCreatedAt(): ?DateTime {
return $this->createdAt;
}
}
trait Loggable {
public function log(string $msg): void {
echo "[" . static::class . "] $msg";
}
}
// a class can USE MULTIPLE traits — their methods become part of the class
class Article {
use Timestampable, Loggable; // mix in BOTH traits' methods
}
$a = new Article();
$a->setCreatedAt(); // from Timestampable
$a->log("created"); // from Loggable
トレイトはメソッド/プロパティのバンドルです。クラスは1つ以上のトレイトをuseして、メンバーをミックスインします。共通の親から継承することなく機能を取得します。
トレイト vs 継承 vs インターフェース
Inheritance (extends) → single parent, "is-a", inherits implementation
Interface → a CONTRACT (signatures only, no code), multiple allowed
Trait → reusable IMPLEMENTATION (actual code), multiple allowed, NO contract
→ Interfaces say WHAT a class can do; traits provide HOW (shared code).
They're often used together: implement an interface, use a trait for the impl.
競合の解決
class X {
use TraitA, TraitB {
TraitA::hello insteadof TraitB; // if both define hello(), pick TraitA's
TraitB::hello as helloB; // alias TraitB's version
}
}
2つのトレイトが同じメソッドを定義する場合、PHPは明示的に競合を解決することを要求します。
なぜ重要なのか
トレイトは関連のないクラス間でコードを再利用するための重要なPHP機能で、実際の制限を解決しています。PHPは単一継承のみを許可しているため、トレイトは水平的な再利用(mixin)を提供し、共通の親を共有しないクラス間で一般的な機能(ロギング、タイムスタンプ、ソフトデリート、シリアライゼーションヘルパー)を共有できます。
トレイトはPHPフレームワーク(LaravelのEloquentはSoftDeletesやHasFactoryのようなモデル動作に広くトレイトを使用)で広く使用されているため、それらを理解することは価値があります。つまり、あなたは常にそれらに遭遇し、使用します。
トレイトが継承とどのように異なるか(is-a関係なしの再利用)、およびインターフェースとどのように異なるか(トレイトは実際の実装/コードを提供し、インターフェースは契約/署名のみを定義します。この2つはしばしば組み合わされます。インターフェースは機能を宣言し、トレイトは共有実装を提供します)を知ることは、それらを適切に使用するために重要です。
トレイトは単一継承だけではできないDRYで合成的な設計を実現し、再利用可能なPHPコードを書くためと、それらの周りに構築されたフレームワークを理解するための実用的でよく遭遇する知識になります。(注意:トレイトを過度に使用すると、動作の出所が不明確になる可能性があるため、デフォルトではなく、genuine cross-cutting再利用のために使用してください。)
