PHP - Achieving Polymorphism

Polymorphism in advanced PHP can be achieved through several mechanisms, primarily using method overriding, inheritance, and interfaces. Let's explore how to achieve polymorphism using these techniques:

Method Overriding and Inheritance (Runtime Polymorphism):

Consider a scenario with a base class Animal and two subclasses Dog and Cat. All classes have a common method makeSound() that represents the sound each animal makes.

class Animal {
  public function makeSound() {
      // Common sound implementation
  }
}
class Dog extends Animal {
  public function makeSound() {
      return "Woof!";
  }
}
class Cat extends Animal {
  public function makeSound() {
      return "Meow!";
  }
}

By overriding the makeSound() method in the Dog and Cat classes, you achieve polymorphism. You can treat instances of Dog and Cat as instances of the common Animal class and call the makeSound() method on them.

$dog = new Dog();
$cat = new Cat();
echo $dog->makeSound();  // Output: Woof!
echo $cat->makeSound();  // Output: Meow!

Interfaces (Compile-Time Polymorphism):

Interfaces provide a way to define a contract that classes must follow. Different classes implementing the same interface can be treated interchangeably based on that interface.

interface Shape {
  public function calculateArea();
}
class Circle implements Shape {
  private $radius;
  public function __construct($radius) {
      $this->radius = $radius;
  }
  public function calculateArea() {
      return pi() * $this->radius * $this->radius;
  }
}
class Rectangle implements Shape {
  private $width;
  private $height;
  public function __construct($width, $height) {
      $this->width = $width;
      $this->height = $height;
  }
  public function calculateArea() {
      return $this->width * $this->height;
  }
}

Here, both Circle and Rectangle classes implement the Shape interface and provide their own implementation for the calculateArea() method. You can treat any object implementing the Shape interface as a Shape object and call the calculateArea() method on them.

function printArea(Shape $shape) {
  echo "Area: " . $shape->calculateArea() . "\n";
}
$circle = new Circle(5);
$rectangle = new Rectangle(4, 6);

printArea($circle);     // Output: Area: 78.539816339745

printArea($rectangle);  // Output: Area: 24

In both cases, you achieve polymorphism by treating objects of different classes uniformly based on shared methods or interfaces. This allows you to write more flexible and extensible code that can work with a variety of objects seamlessly.