Lab 01: Traits, Abstract Classes & Interfaces
Objective
Master PHP's code-reuse mechanisms: traits for horizontal code sharing, abstract classes for enforced template patterns, and interface contracts for polymorphic type systems. Build a product discount system that demonstrates all three working together.
Background
PHP uses single inheritance — a class can only extend one parent. Traits solve this limitation by providing "mixins" — reusable method bundles that are copy-pasted into a class at compile time. Abstract classes enforce a template method pattern: they define the algorithm skeleton but leave specific steps to subclasses. Interfaces define contracts: any class implementing an interface must provide all listed methods, enabling duck-typed polymorphism without inheritance.
Time
30 minutes
Prerequisites
PHP Foundations Lab 07 (OOP), Lab 08 (Inheritance)
Tools
Docker:
zchencow/innozverse-php:latest
Lab Instructions
Step 1: Traits for horizontal reuse
A trait is a group of methods intended for reuse. Unlike a parent class, you can use multiple traits in one class. The methods are literally copied into the class body — there is no runtime dispatch overhead. Traits can have properties too, but they must be compatible with any property declared in the using class.
💡 Traits are compile-time copy-paste, not runtime dispatch. When PHP encounters
use Timestampable, it copies all trait methods directly into the class definition. This means there is zero performance overhead — calling$p->setCreatedAt()is identical to calling a method defined directly inProduct. The PHP manual says: "Traits are a mechanism for code reuse in single inheritance languages."
📸 Verified Output:
Step 2: Trait conflict resolution
When two traits define the same method name, PHP throws a fatal error — you must resolve the conflict explicitly using insteadof and as.
📸 Verified Output:
Step 3: Abstract classes — Template Method pattern
An abstract class cannot be instantiated directly. It defines an algorithm skeleton with abstract methods that must be implemented by concrete subclasses. This is the Template Method design pattern — the parent defines the steps, subclasses fill in the details.
📸 Verified Output:
Step 4: Interfaces — polymorphic contracts
An interface is a pure contract: no method bodies, no properties (except constants). Any class implementing the interface guarantees it has those methods. This enables dependency injection — you type-hint on the interface, and any implementation works.
📸 Verified Output:
Summary
trait
use multiple traits in one class
Shared behaviour across unrelated classes
abstract class
Can't instantiate; defines template
Algorithm skeleton with variation points
interface
Pure contract; implement multiple
Decoupled type system, dependency injection
insteadof
Trait conflict resolution
Multiple traits with same method name
Priceable&Taxable
Intersection type hint
Require multiple interfaces simultaneously
Further Reading
Last updated
