Abstract classes offer shared behavior and enforce subclass method contracts.
The examples focus on the operation itself, including the important distinction: Interfaces declare contracts without forcing one shared implementation.
What It Does
Use the examples below to observe the behavior on a small dataset before extending it to application code.
Before You Start
Read the input requirements before applying this pattern to production data.
Example 1: Basic Use
The base class supplies shared logic and requires subclasses to implement the missing operation.
<?php
abstract class Notification {
abstract public function channel(): string;
public function label(): string { return "Send by " . $this->channel(); }
}
class EmailNotification extends Notification { public function channel(): string { return "email"; } }
echo (new EmailNotification())->label();
Output from a successful local PHP 8.4 run:
Send by email
Example 2: Checking Behavior
The base class supplies shared logic and requires subclasses to implement the missing operation. This distinguishes inherited behavior from the abstract declaration itself.
<?php
abstract class Notification {
abstract public function channel(): string;
public function label(): string { return "Send by " . $this->channel(); }
}
class EmailNotification extends Notification { public function channel(): string { return "email"; } }
echo (new EmailNotification())->channel();
Output from a successful local PHP 8.4 run:
email
Example 3: Practical Example
The base class supplies shared logic and requires subclasses to implement the missing operation. This distinguishes inherited behavior from the abstract declaration itself.
<?php
abstract class Notification {
abstract public function channel(): string;
public function label(): string { return "Send by " . $this->channel(); }
}
class EmailNotification extends Notification { public function channel(): string { return "email"; } }
echo (new ReflectionClass(Notification::class))->isAbstract() ? "abstract" : "concrete";
Output from a successful local PHP 8.4 run:
abstract
Important Behavior and Edge Cases
An abstract base class cannot be instantiated, and overusing inheritance couples otherwise independent behavior.
Comparison with Related Approaches
| Approach | Difference |
|---|---|
| Using Abstract Base Classes | Abstract classes offer shared behavior and enforce subclass method contracts. |
| Related API or alternative | Interfaces declare contracts without forcing one shared implementation. |
Common Beginner Mistakes
| Mistake | Correct approach |
|---|---|
| Ignoring the operation-specific limits | An abstract base class cannot be instantiated, and overusing inheritance couples otherwise independent behavior. |
| Confusing it with a related API | Interfaces declare contracts without forcing one shared implementation. |
Key Takeaways
- Abstract classes offer shared behavior and enforce subclass method contracts.
- An abstract base class cannot be instantiated, and overusing inheritance couples otherwise independent behavior.
- Interfaces declare contracts without forcing one shared implementation.
Use Using Abstract Base Classes when its documented behavior matches the problem. Test the relevant edge cases in your own runtime before deploying it.