Interfaces and Abstract Classes in PHP: Your Friendly Guide to Object-Oriented Programming

Interfaces and Abstract Classes in PHP: Your Friendly Guide to Object-Oriented Programming

Interfaces and Abstract Classes in PHP

Introduction

Imagine you're designing a transportation system for a city. You want different types of vehicles to follow certain rules and have specific capabilities. This is exactly where interfaces and abstract classes come into play in PHP's object-oriented programming!

What are Interfaces?

Think of an interface like a contract or a job description. It defines what methods a class MUST implement, without specifying HOW they should be implemented.

Real-Life Analogy: Restaurant Staff Contract

interface StaffMember {
    public function work(): void;
    public function getTimetable(): array;
    public function calculateSalary(): float;
}

class Waiter implements StaffMember {
    public function work(): void {
        echo "Taking orders and serving customers";
    }

    public function getTimetable(): array {
        return ['morning', 'evening'];
    }

    public function calculateSalary(): float {
        return 2000 * 0.5; // Base salary calculation
    }
}

class Chef implements StaffMember {
    public function work(): void {
        echo "Preparing delicious meals";
    }

    public function getTimetable(): array {
        return ['lunch', 'dinner'];
    }

    public function calculateSalary(): float {
        return 3000 * 0.7; // Base salary calculation
    }
}

In this example, StaffMember is an interface that ensures every staff member has methods to work, get their timetable, and calculate salary. Each role (Waiter, Chef) implements these methods differently.

Abstract Classes: A More Flexible Blueprint

An abstract class is like a partially completed blueprint. It can have both abstract (unimplemented) and concrete (implemented) methods.

Real-Life Analogy: Vehicle Manufacturing

abstract class Vehicle {
    // Concrete method (implemented)
    public function start(): void {
        echo "Engine is starting...";
    }

    // Abstract method (must be implemented by child classes)
    abstract public function calculateFuelEfficiency(): float;

    // Concrete method with some default behavior
    public function park(): void {
        echo "Vehicle is being parked safely";
    }
}

class Car extends Vehicle {
    public function calculateFuelEfficiency(): float {
        return 15.5; // kilometers per liter
    }
}

class Motorcycle extends Vehicle {
    public function calculateFuelEfficiency(): float {
        return 25.3; // kilometers per liter
    }
}

Key Differences

Interfaces

  • Can only declare method signatures

  • A class can implement multiple interfaces

  • No method implementations

  • Used when you want to define a contract

Abstract Classes

  • Can have both abstract and concrete methods

  • Can only extend one abstract class

  • Can have properties and method implementations

  • Used when you want to provide a base implementation

When to Use What?

Use Interface When:

  • You want to define a contract

  • Multiple unrelated classes need to implement the same methods

  • You need multiple inheritance-like behavior

Use Abstract Class When:

  • You want to provide a common base implementation

  • You have some default methods that all child classes should inherit

  • You want to share code among closely related classes

Best Practices

  1. Keep interfaces small and focused

  2. Use meaningful, descriptive names

  3. Prefer composition over inheritance

  4. Use type hinting for better code readability

Common Pitfalls to Avoid

  • Don't create overly complex hierarchies

  • Avoid deep inheritance trees

  • Don't force unrelated classes to implement methods they don't need

Practical Example: Smart Home Devices

interface SmartDevice {
    public function turnOn(): void;
    public function turnOff(): void;
    public function getStatus(): string;
}

abstract class BaseSmartDevice implements SmartDevice {
    protected $name;
    protected $isOn = false;

    public function __construct(string $name) {
        $this->name = $name;
    }

    public function getStatus(): string {
        return $this->isOn ? "On" : "Off";
    }
}

class SmartLight extends BaseSmartDevice {
    public function turnOn(): void {
        $this->isOn = true;
        echo "{$this->name} light is now on";
    }

    public function turnOff(): void {
        $this->isOn = false;
        echo "{$this->name} light is now off";
    }
}

class SmartThermostat extends BaseSmartDevice {
    private $temperature;

    public function turnOn(): void {
        $this->isOn = true;
        $this->temperature = 22; // Default temperature
        echo "{$this->name} thermostat is activated";
    }

    public function turnOff(): void {
        $this->isOn = false;
        $this->temperature = 0;
        echo "{$this->name} thermostat is deactivated";
    }
}

Conclusion

Interfaces and abstract classes are powerful tools in PHP's object-oriented programming. They help you create more structured, maintainable, and flexible code. Think of them as blueprints and contracts that guide how your classes should be designed and behave.

Remember, great code is not just about making things work, but making them work intelligently and consistently!