Traits vs Inheritance

Traits Versus Inheritance and Composition

Inheritance says "is a", composition (Composition) says "has a", and a trait says "contains a copy of". A trait is not a type, so pair it with an interface: class Product implements HasSlug { use SlugFromTitle; } passes every HasSlug check, and the trait is merely a default implementation that another class may replace.

Three ways to reuse code
Question Inheritance Trait Composition
Creates a type? Yes No (pair it with an interface) Via the collaborator's interface
Swap at run time? No No Yes, inject another object
Sees private state? Only protected Yes, all of it Only the public API
Test in isolation? Through the child Through a host class Yes, with a fake

Use a trait for a small, stateless helper (slugs, timestamps, toArray()) that recurs in unrelated classes. Code with dependencies or state of its own, such as a mailer or a cache, belongs in a collaborator passed to the constructor.