web-dev-qa-db-ja.com

PHPのTraitと抽象クラスの違い

私は最近遭遇しました Traits in PHPそして私はそれらを理解しようとしています。私の研究中に私はこのStack Overflowの質問につまずきました: Traits vs. Interfaces 。受け入れられた答えは次のことを述べています。

インターフェイスは、実装クラスが実装する必要がある一連のメソッドを定義します。

特性が使用されると、メソッドの実装も一緒になります。これはインターフェイスでは発生しません。

これまでのところは良いですが、これはインターフェースと抽象クラスの違いとまったく同じように聞こえます。だから、これは私に次の質問を提起します:

  • PHPのTraitクラスとAbstractクラスの違いは何ですか?

私は1つの抽象クラスからのみ拡張でき、その一方で任意の量の特性を使用できることを認識しています。しかし、これが本当に唯一の違いですか?私はまだ特性とその使用を完全に理解していません。

27
simon

特性を使用すると、クラス間でコードを共有できます特定のクラス階層に強制することなく。すべてのクラスに便利なユーティリティメソッドfoo($bar)を持たせたいとします。特性がなければ、2つの選択肢があります。

  • 各クラスでコードの冗長性を備えて個別に実装する
  • 共通の(抽象)祖先クラスから継承する

どちらのソリューションも理想的ではなく、それぞれにトレードオフがあります。コードの冗長性は明らかに望ましくなく、共通の祖先から継承すると、クラス階層設計の柔軟性が失われます。

特性は、各クラスが個別に「インポート」できる特性にfoo($bar)を実装できるようにすることでこの問題を解決しますが、言語の必要性ではなくビジネスロジック要件に従ってクラス階層を設計できます。

36
deceze

正確ではありません...この目的の公式ドキュメントを引用しましょう。

Traitはクラスに似ていますが、機能をきめ細かく一貫した方法でグループ化することのみを目的としています。 Traitを単独でインスタンス化することはできません。これは、従来の継承への追加であり、動作の水平合成を可能にします。つまり、継承を必要としないクラスメンバーの適用。

そのため、クラスが何らかのロジック/動作を実行できるようにするために、合成を目的にトレイトが使用されます。別のクラスまたは抽象クラスから継承している場合、通常は多態性を目的としており、明確な継承/クラス階層を取得しますが、これは望ましい場合と望ましくない場合があります。

それはすべて、コンテキスト、アーキテクチャ、そしてあなたがまさに何をしようとしているのかにかかっていると思います。

7
walther