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

  • 18
    Like
  • 0
    Comment
More than 1 year has 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に自サイトに記載したもの