PHP 5.4 引入 Trait,解決單繼承限制,實現「橫向代碼復用」。Trait 類似類但不可實例化,提供方法集合讓類組合使用。
當前類方法 > Trait 方法 > 父類方法
// GrahamCampbell\Credentials\Repositories\AbstractRepository
abstract class AbstractRepository { /* 共用基礎方法 */ }
// 分頁功能 Trait
trait PaginateRepositoryTrait {
public function paginate($perPage = 15) { /* ... */ }
}
// Slug 查詢功能 Trait
trait SlugRepositoryTrait {
public function find($slug, array $columns = ['*']) {
$model = $this->model;
return $model::where('slug', '=', $slug)->first($columns);
}
}
namespace GrahamCampbell\BootstrapCMS\Repositories;
use GrahamCampbell\Credentials\Repositories\AbstractRepository;
use GrahamCampbell\Credentials\Repositories\PaginateRepositoryTrait;
use GrahamCampbell\Credentials\Repositories\SlugRepositoryTrait;
class PageRepository extends AbstractRepository
{
use PaginateRepositoryTrait, SlugRepositoryTrait;
// 同時擁有 paginate() 與 find() 方法
}
public function show($slug)
{
$page = PageRepository::find($slug); // 來自 SlugRepositoryTrait
$this->checkPage($page, $slug);
return View::make('pages.show', ['page' => $page]);
}
| 特性 | 繼承 | 介面 | Trait |
|---|---|---|---|
| 關係 | is-a | can-do | has-behavior |
| 多重 | 單一 | 多重 | 多重 |
| 實作 | 可有預設 | 無實作 | 提供實作 |
| 狀態 | 可有屬性 | 無屬性 | 可有屬性 |
use TraitA, TraitB {
TraitA::method insteadof TraitB; // 選擇 TraitA 版本
TraitB::method as methodB; // 別名引入 TraitB 版本
}