Polymorphism
Polymorphism is one of the Four Pillars of Object Oriented Programming.
The word comes from Greek:
Poly = Many
Morph = Forms
Meaning:
One thing can exist in many forms.
What is Polymorphism?
Polymorphism allows different classes to be treated as the same type.
Example:
Player
Zombie
Cow
Skeleton
All are:
Entity
This allows us to write code like:
function process(
Entity $entity
) {
}
The function can now accept:
- Player
- Zombie
- Cow
- ItemEntity
All without rewriting code.
Why Polymorphism Exists
Without polymorphism:
processPlayer();
processZombie();
processCow();
processSkeleton();
Huge duplication.
With polymorphism:
process(
Entity $entity
);
Everything becomes simpler.
Real Life Example
Think about:
Remote Control
Pressing:
Power Button
works for:
- TV
- AC
- Fan
- Speaker
Same action.
Different behavior.
This is polymorphism.
First Example
Parent:
class Animal {
public function sound() {
echo "Unknown";
}
}
Child:
class Dog
extends Animal {
public function sound() {
echo "Bark";
}
}
Another Child:
class Cat
extends Animal {
public function sound() {
echo "Meow";
}
}
Usage:
$animals = [
new Dog(),
new Cat()
];
foreach ($animals as $animal) {
$animal->sound();
}
Output:
Bark
Meow
Same Method
sound()
Different behavior.
This is:
Runtime Polymorphism
Visualization
Animal
│
├── Dog → Bark
├── Cat → Meow
└── Bird → Tweet
Method Overriding
Polymorphism usually works through:
Method Overriding
Parent:
class Animal {
public function move() {
echo "Moving";
}
}
Child:
class Bird
extends Animal {
public function move() {
echo "Flying";
}
}
Child:
class Fish
extends Animal {
public function move() {
echo "Swimming";
}
}
Parent References
Example:
$animal =
new Dog();
This is valid.
Why?
Because:
Dog IS AN Animal
Visualization
Animal
↑
│
Dog
Dynamic Dispatch
Example:
$animal =
new Dog();
$animal->sound();
Output:
Bark
PHP automatically chooses:
Dog::sound()
instead of:
Animal::sound()
This is called:
Dynamic Dispatch
Polymorphic Functions
Example:
function makeSound(
Animal $animal
) {
$animal->sound();
}
Usage:
makeSound(
new Dog()
);
makeSound(
new Cat()
);
Output:
Bark
Meow
Why This is Powerful
One function.
Unlimited object types.
PocketMine Example
Simplified:
function attack(
Entity $entity
) {
}
Can receive:
Player
Zombie
Cow
Villager
Entity Hierarchy
Entity
│
├── Human
│ └── Player
│
├── Monster
│ ├── Zombie
│ └── Skeleton
│
└── Animal
Real Example
foreach (
$world->getEntities()
as $entity
) {
$entity->setNameTag(
"Hello"
);
}
Every entity receives same method call.
Polymorphism.
instanceof
Sometimes behavior differs.
Example:
if (
$entity instanceof Player
) {
$entity->sendMessage(
"Hello"
);
}
Another:
if (
$entity instanceof Zombie
) {
$entity->setHealth(
100
);
}
Visualization
Entity
↓
instanceof
↓
Player ?
Zombie ?
Cow ?
Interfaces and Polymorphism
Polymorphism becomes even more powerful with interfaces.
Example:
interface Logger {
public function log(
string $message
);
}
Implementations:
class FileLogger
implements Logger {
}
class DiscordLogger
implements Logger {
}
Usage:
function write(
Logger $logger
) {
}
Can accept:
FileLogger
DiscordLogger
DatabaseLogger
Real World Example
Payment System:
PaymentMethod
│
├── PayPal
├── Stripe
└── Crypto
Function:
pay(
PaymentMethod $method
);
Unlimited payment systems.
Another Example
Notification System:
Notifier
│
├── EmailNotifier
├── DiscordNotifier
└── SmsNotifier
Enterprise Example
interface Cache {
}
Implementations:
Redis
Memcached
FileCache
Everything works together.
Polymorphism in Laravel
Laravel internally uses:
Cache Driver
Queue Driver
Mail Driver
Database Driver
All are polymorphic.
Real PocketMine Examples
Commands
Command
│
├── BanCommand
├── KickCommand
└── WarpCommand
Events
Event
│
├── PlayerJoinEvent
├── BlockBreakEvent
└── EntityDamageEvent
Entities
Entity
│
├── Player
├── Zombie
└── Cow
Benefits
1. Less Duplication
One function.
Many object types.
2. Better Extensibility
Add new classes without modifying old code.
3. Cleaner Architecture
Projects remain organized.
4. Easier Maintenance
No giant if statements.
Example
Bad:
if ($type === "dog") {
}
if ($type === "cat") {
}
Good:
$animal->sound();
Open Closed Principle
Polymorphism helps follow:
Open for Extension
Closed for Modification
Add new classes.
No existing code changes.
Common Beginner Mistakes
Giant If Statements
Bad:
if ($animal === "dog")
Use polymorphism.
Excessive instanceof
Sometimes acceptable.
But too much means bad design.
Breaking Inheritance
Methods should maintain behavior contracts.
Best Practices
✅ Prefer interfaces.
✅ Prefer polymorphism over condition chains.
✅ Use inheritance carefully.
✅ Keep common behavior in parent classes.
Exercises
Exercise 1
Create:
Animal
│
├── Dog
├── Cat
└── Bird
Each should override:
sound()
Exercise 2
Create:
Shape
│
├── Circle
├── Square
└── Rectangle
Method:
area()
Exercise 3
Create:
PaymentMethod
│
├── PayPal
├── Crypto
└── Stripe
Method:
pay()
Mini Project
Create:
Entity
│
├── Player
├── Zombie
├── Skeleton
└── Cow
Method:
attack()
Each entity behaves differently.
Quiz
What does polymorphism mean?
Answer
One thing existing in many forms.
Which concept makes polymorphism possible?
Answer
Method overriding.
Can parent references store child objects?
Answer
Yes.
Which operator checks object type?
Answer
instanceof
Summary
Polymorphism allows:
✅ One interface
✅ Multiple implementations
✅ Cleaner code
✅ Extensible systems
✅ Enterprise architecture
Real PocketMine Architecture
Entity
│
├── Player
├── Zombie
├── ItemEntity
└── Animal
Example:
function process(
Entity $entity
) {
$entity->setNameTag(
"Processed"
);
}
Works for every entity type.
This is polymorphism.
References
https://www.php.net/manual/en/language.oop5.polymorphism.php
Next Chapter
➡ Abstraction
➡ Interfaces
➡ Abstract Classes