Get "PHP 8 in a Nuthshell" (Soon includes PHP 8.4)
Amit Merchant

Amit Merchant

A blog on PHP, JavaScript, and more

This is why PHP don't have multiple inheritance

PHP has evolved greatly as a language over the years. From a simple functional scripting language which initially started by Rasmus Lerdorf as his hobby project to supporting object oriented programming features PHP has come a long way.

Although, PHP has been implementing and improving features of object oriented programming in its every release, there is this one feature which is missing and I’ve always wondered why it is not there in PHP all these years. Yes, I’m talking about multiple inheritance.

There is a very logical reason why PHP don’t support multiple inheritance. To learn about this, we need to go into the roots of this very concept. Multiple inheritance actually suffers from the Diamond Problem.

The “diamond problem” (sometimes referred to as the “deadly diamond of death”) is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. If there is a method in A that B and C have overridden, and D does not override it, then which version of the method does D inherit: that of B, or that of C?

Take this for example by assuming PHP is supporting multiple inheritance.

Diamond Problem in inheritance

Let’s say SuperClass is an abstract class declaring some method and ClassA, ClassB are concrete classes.

<?php

class SuperClass
{
    protected function greet()
    {
        echo "Grandparent";
    }
}

// First Parent class
class ClassA extends SuperClass
{
    protected function greet()
    {
        echo "Parent1";
    }
}
 
// Second Parent class
class ClassB extends SuperClass
{
    protected function greet()
    {
        echo "Parent2";
    }
}
 
class ClassC extends ClassA, ClassB
{
    public function test()
    {
        $c = new self();
        $c->greet();
    }
}

As you can see from the code, on calling the method greet() using object ClassC, it’s impossible for the compiler to decide whether it has to call ClassA’s greet() or ClassB’s greet() method. So, this is to avoid such complications, PHP does not support multiple inheritance.

You may also like: A closer look at Invokable classes in PHP

Mitigation of Diamond problem in PHP

One solution to mitigate not having multiple inheritance in PHP is to use traits. Traits are a mechanism for code reuse in single inheritance languages such as PHP which you’d use multiple inheritance for. Basically, traits are like classes except for one fact that you can’t initantiate an instance of a trait. That is like utilising class members directly into the class without needing to instantiate or inherit them.

Below is an example of how you can define a trait and utilize the same in the class.

trait myTrait 
{
    public function whereAmI()
    {
        echo __CLASS__;
    }
}

class Hello
{
    use myTrait;
}

$a = new Hello;
$a->whereAmI(); //Hello

Similarly, you can use multiple traits in a single clss comma-separated like this.

use Hello, World;

You can read further about Traits here.

Another solution here would be to use composition while designing your software. Basically, Composition is the mechanism to reuse code across classes by containing instances of other classes that implement the desired functionality. Check below example.

<?php
class Vehicle
{    
    public function move()
    {
        echo "Move the car";
    }    
}

class Car
{
    private $vehicle;

    public function __construct(Vehicle $vehicle)
    {
        $this->vehicle = $vehicle;
    }

    public function accelarate()
    {    
        $this->vehicle->move();    
    }
}

As you can see, we’ve injected Vehicle class to the Car class through constructor and this way we can access the class members of Vehilcle class into the Car class. Now, if you want to use to use an another class called Tyre in class Car, all you have to do is to inject it’s instance in the constructor like so.

<?php
class Vehicle
{    
    public function move()
    {
        echo "Move the car";
    }    
}

class Tire
{    
    public function addAlloys()
    {
        echo "Adding alloy wheels...";
    }    
}

class Car
{
    private $vehicle;

    private $tire;

    public function __construct(Vehicle $vehicle, Tire $tire)
    {
        $this->vehicle = $vehicle;
        $this->tire = $tire;
    }

    public function accelarate()
    {    
        $this->vehicle->move();    
        $this->tire->addAlloys();
    }
}

This approach is called as “Composition over Inheritance” in object oriented programming and I’ve written a whole article around it.

Learn the fundamentals of PHP 8 (including 8.1, 8.2, and 8.3), the latest version of PHP, and how to use it today with my new book PHP 8 in a Nutshell. It's a no-fluff and easy-to-digest guide to the latest features and nitty-gritty details of PHP 8. So, if you're looking for a quick and easy way to PHP 8, this is the book for you.

Like this article?

Buy me a coffee

👋 Hi there! I'm Amit. I write articles about all things web development. You can become a sponsor on my blog to help me continue my writing journey and get your brand in front of thousands of eyes.

Comments?