【PHP】トレイト(trait)とは? – クラスのコードを再利用する

トレイトと呼ばれる仕組みがあります。

トレイトはクラスでコードを再利用するためのものです。

ここではトレイトについて解説します。

★ 目的

  • トレイトを理解する。
  • トレイトを使えるようになる。

トレイトとは

トレイトはクラスでコードを再利用する仕組みです。

クラスでトレイトの使用を宣言することで、トレイトに定義したメンバー変数やメンバーメソッドをクラスで使うことができるようになります。

継承と似ていますが、トレイトは『コードを再利用する』ことを目的としており、オブジェクトの構造を表現するものではありません。

基本構文

トレイトは定義と使用の2つの基本構文があります。

トレイトの定義

// トレイト
trait トレイト名 {
    
    // クラス変数
    アクセス修飾子 static 変数;

    // メンバー変数
    アクセス修飾子 変数;

    // クラスメソッド
    アクセス修飾子 static function メソッド名() {
        // 処理・・・
    }

    // メンバーメソッド
    アクセス修飾子 function メソッド名() {
        // 処理・・・
    }

}

基本的にクラスと同じですが、classの部分がtraitとなっています。またクラス定数は定義することができません。

トレイトの使用

// クラス
class クラス名 {

    // トレイト
    use トレイト名;

}

クラス内でuseに続いてトレイト名を記述します。もし、複数のトレイトがある場合は、カンマ(,)区切りで記述します。

サンプルコード

次のサンプルコードをご覧ください。

ソースコード

<?php

// トレイト
trait Communication {
    
    // あいさつ文
    private $text;
    
    // あいさつ文を出力する
    public function greeting() {
        echo $this->text."\n";
    }
    
}

// クラス(抽象クラスを継承)
class Person {
    
    // トレイト
    use Communication;
    
    // 名前
    public $name;
    
    // コンストラクタ
    public function __construct($name, $text) {
        $this->name = $name;
        $this->text = $text;
    }
    
    // プロフィールを出力する
    public function profile() {
        echo "私の名前は".$this->name."です。\n";
    }
    
}

$watanabe = new Person('Watanabe You', "こんにちは!");
$watanabe->greeting();
$watanabe->profile();

$nishikino = new Person('Nishikino Maki', "こんばんわ!");
$nishikino->greeting();
$nishikino->profile();

?>

実行結果

こんにちは!
私の名前はWatanabe Youです。
こんばんわ!
私の名前はNishikino Makiです。

このコードの解説は次の表をご覧ください。

行数概要
4行目〜14行目Communicationトレイトを定義。
17行目〜36行目Personクラスを定義し、Communicationトレイトを使用するよう宣言。
38行目〜44行目Personクラスから2つインスタンスを生成し、それぞれでgreetingメソッドとprofileメソッドを呼び出し。

PersonクラスでCommunicationトレイトを使用しているため、各インスタンスからgreetingメソッドが使えており、コンストラクタで$textへもアクセスできています。

また、トレイトを使用するとトレイトの定義がクラスで定義されているといことに等しいため、$textはprivateですが、クラス内の定義とみなされ正常にアクセスできています。

このあたりでも継承との違いを感じられるのではないでしょうか。

複数トレイト

1つのクラスに対して複数のトレイトを使用することができます。

次のサンプルコードは上記コードにCalculationトレイトを追加したものです。

ソースコード

<?php

// トレイト
trait Communication {
    
    // あいさつ文
    private $text;
    
    // あいさつ文を出力する
    public function greeting() {
        echo $this->text."\n";
    }
    
}

// トレイト
trait Calculation {

    // 足し算をする
    public function addition( $x, $y ) {
        $total = $x + $y;
        echo $x." + ".$y." = ".$total."\n";
    }

}

// クラス(抽象クラスを継承)
class Person {
    
    // トレイト
    use Communication, Calculation;
    
    // 名前
    public $name;
    
    // コンストラクタ
    public function __construct($name, $text) {
        $this->name = $name;
        $this->text = $text;
    }
    
    // プロフィールを出力する
    public function profile() {
        echo "私の名前は".$this->name."です。\n";
    }
    
}

$watanabe = new Person('Watanabe You', "こんにちは!");
$watanabe->greeting();
$watanabe->profile();
$watanabe->addition(3, 5);

$nishikino = new Person('Nishikino Maki', "こんばんわ!");
$nishikino->greeting();
$nishikino->profile();
$nishikino->addition(7, 9);

?>

実行結果

こんにちは!
私の名前はWatanabe Youです。
3 + 5 = 8
こんばんわ!
私の名前はNishikino Makiです。
7 + 9 = 16

31行目のように複数のトレイトを使用する場合はカンマ(,)区切りでトレイトを記述します。

まとめ

トレイトはクラスのコードを再利用するための仕組みです。

継承とはことなり、クラス自体に定義されたものとみなされるため、privateな定義もクラスから使えるようになります。

フレームワークなどでは頻繁に使われるので、覚えておきましょう。