PHP
trait

PHPで複数のクラスをextendsしたい

More than 5 years have passed since last update.

PHP5.4以降でtraitという機能が追加されました。

http://php.net/manual/ja/language.oop5.traits.php

クラスAをextendsしてるけど、ここに追加でクラスBとクラスCもextendsしたい、そんな要求を概ね叶えてくれる機能です。

<?php

// 基底クラス
class A{
public function hoge(){
print('クラスAのメソッドhoge');
}
}

// trait
trait B{
public function hoge(){
print('トレイトBのメソッドhoge');
}
public function fuga(){
print('トレイトBのメソッドfuga');
}
public function foo(){
print('トレイトBのメソッドfoo');
}
}

trait C{
public function fuga(){
print('トレイトCのメソッドfuga');
}

private $int = 1; // プロパティ
}

// Aを継承したクラス
class D extends A{
// トレイトB,Cを使用
use B, C{
// 被っているメソッドfugaはBを使用
B::fuga insteadof C;
}

// @Override
public function foo(){
print('クラスDのメソッドfoo');
}

// トレイトのprivateを参照可能
public function getInt(){
print($this->int);
}
}

// 優先順位は自分自身 > trait > 基底クラス
$d = new D();
$d->hoge(); // トレイトBのメソッドhoge
$d->fuga(); // トレイトBのメソッドfuga
$d->foo(); // クラスDのメソッドfoo
$d->getInt(); // 1

interfaceではメソッドの定義しか行えずロジックは書けませんでした。

クラスとはひとつしかextendsできないため、extends A, B, Cができませんでした。

トレイトを使うことによってこれらの問題点を解消し、ロジックを書いたうえで複数extendsのようなことを行うことができるようになります。

トレイト内のprivateな値も参照できていることから、普通のextendsより強い結びつきということがわかります。

実際はもっと単純に、useしたtraitは全部合わせてひとつのクラスと看做すと考えればよいでしょう。

要するにもうPartial classってことでいいよね。

※2013/06/21に自サイトに記載したもの