web-dev-qa-db-ja.com

トレイトは親メソッドを参照する必要がありますか?

traitのメソッドがparent::methodsを参照している場合、または使用中のクラスにあると想定されているメソッドを参照している場合、コードの匂いですか?

ランダム(無意味)な例

trait foo
{
    public function bar()
    {
        return parent::bar() . 'baz';
    }

    public function format($text)
    {
        $format = true;
        return $this->parse($text, $format);
    }
}

これらのメソッドはclass実装で移動されますか?

traitの中に、依存関係のないメソッドのみを含める必要がありますか?

9
Kamafeather

トレイトが埋め込まれているクラスのメソッドにトレイトが依存している場合は問題ありません。しかし、これらの依存関係は abstract function 。 PHPは、そのようなメソッドが実際に存在することを確認できます。

しかし、トレイトはメソッドをオーバーライドすべきではありません。それはやや混乱する行動です。代わりに、トレイトのメソッドに別の名前を付けます。この特定の例では、特性が埋め込まれているクラスの基本クラスのメソッドに依存しています。これは非常にあいまいな依存関係です。 ドキュメントの優先例 と比較してください。

代わりに抽象クラスを使用しないのはなぜですか?複数の特性を持つことができますが、基本クラスは1つだけです。したがって、特性はより一般的であり、複数のクラスで使用する便利な関数のバンドルに役立ちます。 formatメソッドはこの良い例です。より明確に書かれると、次のようになります。

trait Formatter
{
    abstract public function parse($text, $format);

    public function format($text)
    {
        $format = true;
        return $this->parse($text, $format);
    }
}
12
amon

はい、それはコードのにおいです。コードをより移植性の高いものにするためにトレイトが使用されている場合、この種のことが移植性を低下させます。あなたはそれをすべきではありません。より具体的な例がなければ、あなたがしなければならないことは、そのbarメソッドを抽象に入れてそれを拡張することです。そのアプローチは、トレイトがバーを持たないクラスに追加される潜在的なランタイムバグを回避します。

7
zquintana