PHPのトレイトを使うと多重継承に相当する処理を記述できることを3種類の帳票の例で紹介しました。
1 | trait A |
トレイトを使い込む内に1つの制限が見えてきました。それはダイヤモンド継承ができないことです(現在ではこの問題は解消されています。恐らくPHP7.3で解消されたものと思われます)。
右のコードで、クラスDは、トレイトBとトレイトCを取り込んでいます。トレイトB、トレイトC共にトレイトAを取り込んでいます。トレイトAはメソッドaを持っています。この場合、PHPではメソッドaが衝突しているという意味のエラーが発生します。トレイトBとトレイトCのそれぞれにメソッドaがあるとみなすようです。
私は共通のトレイトAの実体は1つなのでエラーにならないことを期待しました。includeとinclude_onceに例えれば、includeではなくinclude_onceに相当する動作を期待したのですが実際にはincludeに相当する動作をします。
この回避方法としてはトレイトB、トレイトCでトレイトAを取り込まないで、クラスDでトレイトA、B、Cを取り込むことが考えられます。
但しトレイトB、トレイトCがトレイトAを取り込むことがコード上で明示されないというデメリットがあります。これについてはコメントで注釈しています。
トレイトB、トレイトCをコーディングするとき、トレイトAに関するメンバーをIDEが補完してくれない可能性があります。PHPStormではトレイトをuseしているクラス、この場合はクラスDを通じてAのメンバーを候補に表示してくれます。Eclipseは調査していません。