traitってどこまでできるんだろうなーとちょっと調べた。調べた環境はPHP5.6だけど基本5.4以上なら一緒のはず。
<?php
interface HogeInterface
{
function hoge();
function fuga(array $monge);
}
trait HogeTrait
{
function hoge()
{
echo 'hogehoge.', PHP_EOL;
}
function mongeeeeee(array $monge)
{
array_walk($monge, function($v){ echo $v, PHP_EOL; });
}
}
class HogeClass implements HogeInterface
{
use HogeTrait
{
// interfaceで定義してる名前に合わせる
mongeeeeee as fuga;
}
// ↓このようなヒンティングは可能だが意味が無い。
// てかタイプヒンティングは利用時までチェックすらされない
function traitor(HogeTrait $trait)
{
$trait->mongeeeeee(['mon', 'mon', 'mon']);
}
function makeItHoge(HogeInterface $impl)
{
$impl->hoge();
}
}
$hoge = new HogeClass();
$hoge->hoge(); // Traitで実装したメソッド
$hoge->fuga([1,2,3]); // TraitでAsを使って実装したメソッド
$hoge->makeItHoge($hoge); // Interfaceとして振る舞わせているつもり。勿論大丈夫
//$hoge->traitor($hoge); // ヒンティングしてる仮引数の型と一致せずエラーになる。
//$hoge->traitor(new HogeTrait()); // trait単体でnewもできないし詰んだ
- traitは型ではない
- interfaceがわりには使えない
- 当然「実装のあるinterface」ではない
- traitをinterfaceのメソッド実装に使うことはできる
- asを使って名前を変えて適合させるでもOK
- あるinterfaceとセットでデフォルト実装を提供するtraitを作っておくみたいなことができる
- むしろそういうのこそ活きるっぽい