How abstract classes and methods work in PHP

PHP abstract classes

This is a super-simple tutorial about abstract classes in PHP.

Keep reading to learn how PHP class abstraction works, how to use abstract methods, and all the abstraction rules that you need to know.

Contents


What are PHP abstract classes?

The idea of an “abstract class” can be confusing.

So, let’s start by making it clear what abstract classes actually are.

A standard class is like an instruction sheet for PHP.
When you create an object of that class, PHP follows the instructions and creates the object.

For example, you can write a “Computer” class with attributes such as CPU type, memory and power consumption, and with methods such as turn on, turn off and stand-by.

This class provides everything that is needed to create a Computer object, because all the attributes and methods are clearly defined.

An abstract class, on the other hand, is like a requirements sheet. It tells what an object must have, but it doesn’t provide enough information to actually create the object.

For example, you can write an abstract class named “Electronic” that represents a generic electric device.

This class defines some required attributes and methods, such as the power consumption attribute and the turn on/off methods.

However, it does not provide enough information to create an object.

Imagine if someone asks you to draw an electric device. It’s too… abstract, right? You would ask in return: “what kind of electric device, exactly?”

And that’s exactly what happens with abstract classes.

You cannot create an object of an abstract class, but you must first create a child class that completes the abstract class by implementing the abstract class requirements.

Standard classAbstract class
Fully defines properties and methodsOnly tells the required properties and methods
Can create an object of this classCannot create an object of this class

Now, let’s see how this works in PHP.


The abstract PHP keyword.

To tell PHP that a class is an abstract class, you need to use the abstract keyword like this:


abstract class Electronic
{
   public $pwrConsumption;
   //...
}

The Electronic class is defined as abstract.

You cannot create objects of this class, but you must create a child class first.

You can also add  abstract methods to the class.

An abstract method is a class method that only defines the method’s signature, without the body.

Like this:


abstract class Electronic
{
   public $pwrConsumption;
   
   abstract public function turnOn();
   abstract public function turnOff();
}

Remember: abstract methods do not have the body, while non-abstract methods must have it.

A class that contains at least one abstract method, must be an abstract class.

So, the following is an error because there is no abstract keyword before the class:


class MyClass
{
   abstract public function myMethod();
}

On the other hand, you can define a class as abstract even if it doesn’t contain any abstract method, or any method at all.

Put simply: any class can be abstract. But if there is at least one abstract method, then the class must be abstract.

The role of abstract methods is to set a requirement for children classes.

When you create a child class, you must override the parent class’ abstract methods and give them a body.

In other words, abstract methods force children classes to implement those methods, without the need for the base class to implement it.

For example:


abstract class MyClass
{
   abstract public function myMethod();
}

class ConcreteClass extends MyClass
{
   public function myMethod() {
      echo "Hello";
   }
}

To sum up, here are the rules you need to remember:

  • If a class is abstract, you cannot create an object of that class.
  • Abstract methods only define the method’s signature, without the body.
  • If a class has at least one abstract method, then the class too must be abstract.
  • When you define a child class of an abstract class, you must write the body of all the abstract methods of the parent class.

You can find all the PHP abstraction rules here.

When to use class abstraction.

Now you may ask: why do you need abstract classes in the first place?

Let’s think about how OOP inheritance works:

You have a generic class, and then you can write children classes that are specific versions of the base class.

When you have a piece of code that works with objects of the base class, this code also works with objects of the children classes.

Here is an example taken from my class inheritance tutorial:


class Bird
{
   public $wingspan;
   public $colors;
}

class Parrot extends Bird
{
}

function watchBird(Bird $bird)
{
   echo 'Here is a bird!';
}

$bird = new Bird();
watchBird($bird);

$parrot = new Parrot();
watchBird($parrot); /* This works just fine. */

Ok, now let’s see another example.

Let’s say that you are building a warehouse storage app. In this warehouse, stuff is stored in three types of boxes: wooden boxes, plastic boxes, and metal boxes. So you write a PHP class for each box type: WoodenBox, PlasticBox and MetalBox.

These classes have common properties such as weight, size, the list of items etc. For example:


class WoodenBox
{
   public $length;
   public $width;
   public $height;
   //...
}

class PlasticBox
{
   public $length;
   public $width;
   public $height;
   //...
}

class MetalBox
{
   public $length;
   public $width;
   public $height;
   //...
}

You can see how it makes sense to write a common base class where to group all the common properties and methods.

Let’s call this base class Box:


class Box
{
   public $length;
   public $width;
   public $height;
   //...
}

class WoodenBox extends Box
{
   //...
}

class PlasticBox extends Box
{
   //...
}

class MetalBox extends Box
{
   //...
}

Now that you have a common base class, you can write PHP code that works with any Box child class object, like this:


function getVolume(Box $myBox)
{
   $volume = $myBox->length * $myBox->width * $myBox->heigh;
   return $volume;
}

$woodenBox = new WoodenBox();
echo getVolume($woodenBox);

$plasticBox = new PlasticBox();
echo getVolume($plasticBox);

$metalBox = new MetalBox();
echo getVolume($metalBox);

But here’s the thing:

There’s no such thing as a “generic” box in your warehouse.

So, while it makes sense to group the three types of boxes into a common Box class, it does not make sense to have objects of the Box class, because no “generic” boxes exist in your warehouse.

In other words, you want every Box object to be a WoodenBox, a PlasticBox or a MetalBox.

This is done by defining the Box class as abstract.

Making Box abstract prevents you from creating generic Box objects, but still lets you keep all the advantages of class inheritance:


abstract class Box
{
   public $length;
   public $width;
   public $height;
   //...
}

class WoodenBox extends Box
{
   //...
}

class PlasticBox extends Box
{
   //...
}

class MetalBox extends Box
{
   //...
}

Inheriting from abstract classes.

Inheriting from an abstract class follows the same rules as normal class inheritance:

  • The visibility of the child’s methods must be the same as the parent’s or less restricted.
  • The child methods’ arguments must be compatible with the base class methods (except for the constructor).

On top of those, there are two additional rules.

First: you must override all abstract methods from the base class and implement them by writing their bodies.

For example:


abstract class Electronic
{
   abstract public function turnOff();
}

class Computer extends Electronic
{
   public function turnOff()
   {
     // save open files...
     // close apps...
     // power off pc...
   }
}

The only exception to this rule is when you want to define the child class as abstract.

In this case you are free to leave one or more methods as abstract.

For example:


abstract class Electronic
{
   abstract public function turnOff();
}

abstract class MicroElectronic extends Electronic
{
   //...
}

Second rule: you cannot use the parent:: keyword to call an abstract method from the parent class.

So, this is an error:


abstract class Electronic
{
   abstract public function turnOff();
}

class Computer extends Electronic
{
   public function turnOff()
   {
     // save open files...
     // close apps...
     // power off pc...
     parent::turnOff(); // -> This is an error.
   }
}

Conclusion

In this tutorial you learned what abstract classes are and how they work in PHP.
You also learned about abstract methods, how classes with abstract methods must be abstract, and how inheritance works with abstract classes.

There will be more tutorials about OOP.
If there are specific topics you would like me to write about, let me know in the comments.

Be sure to subscribe to my free newsletter to get my weekly tips!

Alex

MySQLi vs PDO: which one is best for you?

Get my weekly PHP tips and the bonus PDF, absolutely free.

The images used in this article have been downloaded from Freepik.