Polymorphism (OOP Principle)
Polymorphism is a big word, but it's not as scary as it sounds. In object-oriented programming (OOP), polymorphism is the concept that objects of different types can be accessed through the same interface.
Here's a simple way to understand it: think of a remote control. It's an interface to operate various devices like a TV, a DVD player, or a stereo system. Each device performs different actions when the buttons on the remote are pressed, but you use the same interface (the remote) to control all of them. This is similar to polymorphism.
Polymorphism in Action
In PHP, polymorphism is often implemented using interfaces or abstract classes. For instance, you might define an interface with the method makeSound()
.
interface Animal {
public function makeSound();
}
Then, various classes like Dog
, Cat
, and Bird
can implement this interface and provide their own implementation of the makeSound()
method.
class Dog implements Animal {
public function makeSound() {
echo "Woof!";
}
}
class Cat implements Animal {
public function makeSound() {
echo "Meow!";
}
}
Lastly, we can define a function that accepts an instance of a class that inherits from the Animal
class like so:
function playSound(Animal $animal) {
$animal->makeSound();
}
$dog = new Dog();
$cat = new Cat();
playSound($dog); // Outputs: Woof!
playSound($cat); // Outputs: Meow!
In this example, playSound()
function doesn't need to know what type of Animal it's dealing with. It just calls the makeSound()
method, and it's up to the object to determine how to react. This is polymorphism in action: the ability to treat different objects in the same way through a common interface.
Polymorphism with Abstract Classes
Polymorphism with abstract classes works in a similar way to interfaces but with some differences. Abstract classes, unlike interfaces, can contain some implemented methods along with abstract ones. An abstract method is a method that is declared but not implemented in the code.
Let's take an example: Suppose you're creating a video game with different types of monsters. Each monster has a name and a sound that it makes. However, the way each monster attacks is different. Here's how you might structure that with an abstract class:
abstract class Monster {
protected $name;
protected $sound;
public function __construct($name, $sound) {
$this->name = $name;
$this->sound = $sound;
}
public function makeSound() {
echo $this->sound;
}
abstract public function attack();
}
class Zombie extends Monster {
public function attack() {
echo $this->name . " attacks with its hands!";
}
}
class Ghost extends Monster {
public function attack() {
echo $this->name . " attacks with a scary scream!";
}
}
In this setup, Monster
is an abstract class that provides some common functionality (the makeSound()
method) but also requires any classes that extend it to provide their own implementation of the attack()
method.
Here's how you might use this setup:
function startAttack(Monster $monster) {
$monster->makeSound();
$monster->attack();
}
$zombie = new Zombie("Zombie", "Groans");
$ghost = new Ghost("Ghost", "Boo");
startAttack($zombie); // Outputs: Groans Zombie attacks with its hands!
startAttack($ghost); // Outputs: Boo Ghost attacks with a scary scream!
As you can see, the startAttack()
function can take any object that is a subclass of Monster
. It calls both the makeSound()
and attack()
methods on the object, and it doesn't care what type of Monster it is dealing with. This is polymorphism - the same method call behaves differently depending on the type of object it is called on.
Key Takeaways
- Polymorphism is a concept in OOP that allows objects of different classes to be accessed through the same interface, enabling different objects to respond uniquely to the same method call.
- Polymorphism in PHP is achieved through interfaces and abstract classes. When a class implements an interface or extends an abstract class, it promises to provide certain methods.
- A class can provide its own implementation of a method that is already defined in its parent class or interface. This is called method overriding and is a key aspect of polymorphism.
- With polymorphism, you can write code that works with objects of the superclass, yet each subclass will perform those actions in a way appropriate to itself, thus allowing for more versatile code.