Some of the PHPs Object Model Features: Interfaces, Traits and Abstract Classes

Muhammad Anwar Hussain
7 min readJul 19, 2019

Object Oriented Programming: Interfaces, Traits, Abstract Methods and Abstract Classes

When we talk about Object Oriented Programming in PHP, there are three most exciting features out of the complete object model get into involve frequently in many applications and these are Interfaces, Traits and Abstract Classes. Literally, the concept of Interface and Abstract in PHP is quite relevant to the concept of those in other OOP languages. But Traits in PHP is something different.

According to the PHP documentation, Traits are a mechanism for code reuse in single inheritance languages such as PHP. Purposely,Traits are introduced in PHP language to resolve the limitation of single inheritance and to give a flavor of multiple inheritance. Unlike other OOP languages, PHP does not support the concept of multiple inheritance. To be precise, in PHP a child class can not be derived from more than one parent classes. Consequently, Traits are the strategy for playing an important role in PHP to get rid of the situation. Basically, a Trait can be defined by the use of trait keyword and it can be inserted within a class by the use of use keyword. Nevertheless, Traits can not be instantiated by their own during their life time. Last but not least, Traits can define both properties and methods, but they can not define constants.

As of PHP 5, the concept of a Trait represents a set of methods and properties that can be used to extend the functionality of a class. Furthermore, the internal mechanism for combining Traits and Classes is designed in such a way that, it reduces complexity as well as provides the opportunity for producing more standard and readable code. It is mention able that I have dedicated an article only on Traits, so I am not going in details on Traits during the discussion of the examples. However, if somebody is further interested then please, have a look at the article by this Link.

Now, let’s talk about some of the important characteristics of Interfaces and Abstract classes. According to the PHP documentation:

An Interface is the mechanism of specifying which methods a class must implement without telling how these methods are going to be implemented. To be precise, an Interface may consist of only undefined methods, the methods which do not obtain a body. Moreover, an Interface is defined by the use of interface keyword and all the methods consists of an Interface must be public, which is the nature of an Interface. An Interface can extend more than one Interfaces by the extends operator and a class can implement more than one Interfaces with the use of implements operator. For both cases, if it is needed, a comma separator may be used. Last but not least, an Interface can use constants in the same way as a class do except they can not be overridden by an Interface or a class that inherits them.

On the other hand, the class that consist of at least one abstract method is known as Abstract class. An Abstract class is defined by the abstract in conjunction with class keywords. In fact, an abstract method of an Abstract class is simply declared by it’s signature. Now, what is the abstract method, we meant above? A method that does not obtain any implementation, more specifically, a method that does not hold a body, is known as abstract method. Additionally, all the abstract methods of an Abstract class must be defined by the abstract keyword.

In the PHP documentation it also says, an Abstract class may not be instantiated, they only can be extendable by other classes. By the way, we may invoke a non abstract method of an Abstract class without extending it by other classes. For example, a non-abstract static method of an Abstract class can be invoked by itself. Generally, an Abstract class is partially implemented, means that, it may be consist of both abstract and non-abstract methods. Last but not the least, if an Interface is first implemented by an Abstract class and the Abstract class is further extended by another class except any Abstract class then, all the abstract methods must be implemented by that class. During this procedure, if a method of the Interface is not implemented by the Abstract class then either the method can be totally avoided, by not showing it within Abstract class or it can be defined by using abstract keyword. Looks a bit clumsy, hmm! Don’t worry, we will see this scenario by the aid of last example.

In this article, I am going to introduce a number of examples by discussing some basic functionalities of Interfaces, Traits and Abstract classes . The examples are sequentially as follows:

  • interface.php
  • interface_trait.php
  • abstract_trait.php
  • interface_abstract_trait.php

In the first example interface.php, an Interface named Services is introduced and all its methods are implemented by the Train, Ship and Plane classes accordingly as the implementation they needed for getting the services. Now let’s go through the snippet of code below:

class Transport 
{
protected $transport;

function setTransport(Services $s = null)
{
$this->transport = $s;
}

public function getService($serviceName)
{
$this->transport->$serviceName();
}

public function getServicePackage()
{
$this->transport->service_X();
$this->transport->service_Y();
$this->transport->service_Z();
}
}

If we look into the code carefully there is one segment of the code to be noticeable. By using a type hint as Services for the setTransport() method, we basically force our code not to accept any data type outside Train, Ship and Plane objects. By far, these are the objects whereby the Services Interface has been implemented. Imagine for a moment that we are dealing with quite a few number of Interfaces which are implemented by different kind of classes for different purposes, then type hinting can be very effective. Generally, by applying type hinting we can restrict our code from passing any incompatible data types, consequently our code can gain more elegant and standard form.

Let’s give some further explanation to the code. By setting any of the objects whether it is Train, Ship or Plane with the support of Transport object, we can either get a single service or the whole service-package depending on our demand. Let’s say, we want to apply the Ship object for getting a service from the ‘service_X’ method then the action will be as follows:

$transport = new Transport();
$transport->setTransport(new Ship);
$transport->getService('service_X');

According to our code the output will be as follows :

Ship::service_X

At this moment it seems, the code for the 1st example become less clumsy. So here is the final output that will be produced by the interface.php file:

Train::service_X
Train::service_Y
Train::service_Z
Ship::service_X
Ship::service_Y
Ship::service_Z
Plane::service_X
Plane::service_Y
Plane::service_Z

Right now, we want to introduce Traits into our examples and we can do this quite easily by the next example and so forth. It will be seen by the next example that all the methods of the Interface will be defined by a Trait named TransportServices, by providing a complete implementation to each of the methods that any object finally want to achieve. After then, to accomplish the implementation of the Interface by the objects, the Trait will be placed within each of the classes. That’s all! Although it is not a good example for explaining the usability of Traits, but for the shake of simplicity I configure it that way. For your convenience, a better example on Traits can be found by this Link.

In many PHP applications, one of the beauty of using Traits is that, it always gives a compactness to the code and make the code more readable.

Here is the inclusion of the Trait by the following example:

OK, now let’s talk about some basic functionalities of Abstract classes. Fundamentally, an Abstract class can obtain both abstract and non abstract methods, what is the nature of an Abstract class. Now, by the aid of 3rd example, we are going to introduce the Services Abstract class, which is actually created by some modifications of the first one. Here, we have used the Services as Abstract class instead Interface and we have also relocated getServicePackage() method inside the Abstract class. Finally, we have extended the Abstract class by the Train, Ships and Plane objects respectively.

In fact, the procedure for getting output from the code has quite improved what we have seen by the 1st and 2nd examples. We can observe this by the following code:

class Transport 
{
protected $transport;

function setTransport(Services $s = null)
{
$this->transport = $s;
}

public function getService($serviceName)
{
$this->transport->$serviceName($this->transport);
}
}

$transport = new Transport();
$transport->setTransport(new Plane);
$transport->getService('service_X');
$transport->getService('getServicePackage');

In this code we have created the option for getting either a single service or the whole service package by the aid of a single method which is getService().

Here is the complete code for the 3rd example:

Now it is time to glue all the features, that we have discussed until now, with each other and even for doing that, we need to include a few Interfaces and Traits so that, by the end of this discussion, we will achieve a better object oriented model for using the features.

It’s seems to me that after a long discussion, the code become self explanatory. What I want to remark in the last example is that I have commented a group of services for the entertainments inside the Abstract class, and this is the point I have mentioned at the very beginning of this article.

Here is the complete code for the last example:

To sum up, by this article, I have tried to focus on some basic functionalities of Interfaces, Traits and Abstract classes and how to combine them with each other using classes.

Thanks to all for keeping your patience with this long discussion!

Any of yours valuable comments and suggestions about the article beside your claps, would be greatly appreciated.

The PHP row files for this article as well as other programming code for different topics can be found by my GitHub repository.

--

--