I recently came across Traits in PHP and I’m trying to understand them. During my research I stumbled upon this Stack Overflow question: Traits vs. Interfaces. The accepted answer mentions the following:
An interface defines a set of methods that the implementing class must
When a trait is use’d the implementations of the methods come along
too–which doesn’t happen in an Interface.
So far so good but this sounds exactly like the difference between an interface and an abstract class to me. So this raises a follow-up question for me:
- What is the difference between a Trait and an Abstract Class in PHP?
I am aware that I can extend from only one abstract class and on the other hand use any amount of traits. But is this really the only difference? I still don’t completely understand traits and its use.
Traits allow you to share code between your classes without forcing you into a specific class hierarchy. Say you want all your classes to have the convenient utility method
foo($bar); without traits you have two choices:
- implement it individually with code redundancy in each class
- inherit from a common (abstract) ancestor class
Both solution aren’t ideal, each with their different tradeoffs. Code redundancy is obviously undesirable, and inheriting from a common ancestor makes your class hierarchy design inflexible.
Traits solve this problem by letting you implement
foo($bar) in a trait which each class can “import” individually, while still allowing you to design your class hierarchy according to business logic requirements, not language necessities.
Not exactly… Let’s quote official documentation for this purpose:
A Trait is similar to a class, but only intended to group
functionality in a fine-grained and consistent way. It is not possible
to instantiate a Trait on its own. It is an addition to traditional
inheritance and enables horizontal composition of behavior; that is,
the application of class members without requiring inheritance.
So Traits are used for composition purposes to enable the class to perform some logic/behavior. If you’re inheriting from another/abstract class, it’s usually for purposes of polymorphism and you get a distinct inheritance/class hierarchy, which may or may not be desirable.
I think it all depends on the context, on the architecture and on what exactly are you trying to do.