web-dev-qa-db-fra.com

Différence entre Trait et une classe abstraite dans PHP

Je suis récemment tombé sur Traits in PHP and j'essaie de les comprendre. Au cours de mes recherches, je suis tombé sur cette question de débordement de pile: Traits vs. Interfaces . La réponse acceptée mentionne ce qui suit:

Une interface définit un ensemble de méthodes que la classe d'implémentation doit implémenter.

Lorsqu'un trait est utilisé, les implémentations des méthodes se produisent également - ce qui ne se produit pas dans une interface.

Jusqu'ici tout va bien mais cela ressemble exactement à la différence entre une interface et une classe abstraite pour moi. Cela soulève donc une question de suivi pour moi:

  • Quelle est la différence entre un trait et une classe abstraite en PHP?

Je suis conscient que je peux étendre à partir d'une seule classe abstraite et d'autre part utiliser n'importe quelle quantité de traits. Mais est-ce vraiment la seule différence? Je ne comprends toujours pas complètement les traits et son utilisation.

27
simon

Les traits vous permettent de partager du code entre vos classes sans vous forcer dans une hiérarchie de classes spécifique. Supposons que toutes vos classes aient la méthode utilitaire pratique foo($bar); sans traits, vous avez deux choix:

  • l'implémenter individuellement avec une redondance de code dans chaque classe
  • hériter d'une classe ancêtre commune (abstraite)

Les deux solutions ne sont pas idéales, chacune avec ses différents compromis. La redondance de code n'est évidemment pas souhaitable, et hériter d'un ancêtre commun rend la conception de votre hiérarchie de classe inflexible.

Les traits résolvent ce problème en vous permettant d'implémenter foo($bar) dans un trait que chaque classe peut "importer" individuellement, tout en vous permettant de concevoir votre hiérarchie de classe en fonction des exigences de la logique métier, et non des nécessités du langage.

36
deceze

Pas exactement ... Citons la documentation officielle à cet effet:

Un trait est similaire à une classe, mais uniquement destiné à regrouper les fonctionnalités de manière fine et cohérente. Il n'est pas possible d'instancier un trait seul. C'est un ajout à l'héritage traditionnel et permet une composition horizontale du comportement; c'est-à-dire l'application des membres de la classe sans exiger d'héritage.

Les traits sont donc utilisés à des fins de composition pour permettre à la classe d'exécuter une logique/un comportement. Si vous héritez d'une autre classe/abstraite, c'est généralement à des fins de polymorphisme et vous obtenez une hiérarchie d'héritage/classe distincte, qui peut être souhaitable ou non.

Je pense que tout dépend du contexte, de l'architecture et de ce que vous essayez de faire exactement.

7
walther