Challenge 2 — Solution Task: Create an abstract class Employee with a constructor setting $name, an abstract method calculatePay(): float, and a concrete method describe() that echoes the name and calculated pay together. Create two subclasses, SalariedEmployee and HourlyEmployee, each implementing calculatePay() differently. name}: £" . number_format($this->calculatePay(), 2) . "
"; } } class SalariedEmployee extends Employee { public function __construct(string $name, private float $annualSalary) { parent::__construct($name); } public function calculatePay(): float { return $this->annualSalary / 12; } } class HourlyEmployee extends Employee { public function __construct(string $name, private float $hourlyRate, private float $hoursWorked) { parent::__construct($name); } public function calculatePay(): float { return $this->hourlyRate * $this->hoursWorked; } } $salaried = new SalariedEmployee("Priya", 48000); $hourly = new HourlyEmployee("Tom", 15.50, 37); $salaried->describe(); $hourly->describe(); ?> Output: Priya: £4,000.00 Tom: £573.50 Notes: - Employee cannot be instantiated directly with "new Employee(...)" - it exists purely to be extended, and its abstract calculatePay() method guarantees every subclass must provide its own implementation. - describe() is written once, on the abstract parent, and works correctly for both subclasses without any changes - it calls $this->calculatePay(), which resolves to whichever subclass's own version is appropriate for the object it's called on. - Each subclass's own constructor calls parent::__construct($name) to reuse Employee's own name-setting logic, then adds its own additional properties ($annualSalary or $hourlyRate/$hoursWorked) specific to that particular kind of employee.