Get up to 80 % extra points for free! More info:

Lesson 14 - Interfaces in PHP

In the previous exercise, Solved tasks for OOP in PHP lessons 12-13, we've practiced our knowledge from previous lessons.

In the previous lesson, Solved tasks for OOP in PHP lessons 12-13, we put our knowledge of OOP into practice by making a simple visit counter application. Today, we'll be getting into some more theory, we're going to talk about interfaces and continue working with our Human class and its descendants.

Interface

An interface, in programming terms, represents the public methods exposed by a class. In other words, we are able to communicate with a class instance using interfaces without having any sort of contact with anything other than its public methods/members.

An interface can also be defined independently, from outside of the class. An interface does not contain implementation, only method heads. As the name suggests, all it is is an interface :) Once we create it, we can implement it in a class.

Let's give it a try! Create an interface in the class folder, despite the fact that it's technically not actually a class. Create a new file called ProgrammerInter­face.php, and add the following lines to it:

interface ProgrammerInterface
{
    public function program();
}

All we'll include in our ProgrammerInterface interface is the program() method. We could add more, but for our needs, this should be enough.

Now, let's move to our PhpProgrammer.php class. Just to make sure you all remember it what it does:

class PhpProgrammer extends Human
{

    public $ide;

    public function __construct($firstName, $lastName, $age, $password, $ide)
    {
        $this->ide = $ide;
        parent::__construct($firstName, $lastName, $age, $password);
    }

    public function greet()
    {
        echo("Hello world! I'm $this->firstName");
    }

    public function program()
    {
        echo("I'm programming in {$this->ide}...");
    }

}

The PhpProgrammer class inherits from the Human class, calls the parent constructor, overrides the greet() method, and adds a new method names program().

We already know that we can only inherit from a single class in PHP. However, are also able to implement any number of interfaces. We do this by implementing the ProgrammerInterface interface in the class declaration via the "implements" keyword.

class PhpProgrammer extends Human implements ProgrammerInterface

Remember classes are inherited, interfaces are implemented. It makes total sense because inheritance extends a class with a new implementation. Whereas, all an interface does, is force a class to contain some methods. We can implement as many interfaces as we want, separated by commas.

Let's create an instance of PhpProgrammer in index.php:

$phpProgrammer = new PhpProgrammer('Thomas', 'Futile', 28, 'ilovemypassword', 'NetBeans');
echo('OK');
class Human
{

    public $firstName;
    public $lastName;
    public $age;
    private $tiredness = 0;
    public $id;
    private static $peopleCount = 0;
    private $password;

    public function __construct($firstName, $lastName, $age, $password)
    {
        $this->firstName = $firstName;
        $this->lastName = $lastName;
        $this->age = $age;
        self::$peopleCount++;
        $this->id = self::$peopleCount;
        $this->password = $password;
    }

    public function sleep($time)
    {
        $this->tiredness -= $time * 10;
        if ($this->tiredness < 0)
            $this->tiredness = 0;
    }

    public function run($distance)
    {
        if ($this->tiredness + $distance <= 20)
            $this->tiredness += $distance;
        else
            echo("I'm too tired.");
    }

    public function greet()
    {
        echo('Hi, my name is ' .  $this->firstName);
    }

    protected function fullName()
    {
        return $this->firstName . ' ' . $this->lastName;
    }

    public function __toString()
    {
        return $this->firstName . ' - ' . $this->id;
    }

    public static function validPassword($password)
    {
        return (mb_strlen($password) >= 5);
    }

}
interface ProgrammerInterface
{
    public function program();
}
class PhpProgrammer extends Human implements ProgrammerInterface
{

    public $ide;

    public function __construct($firstName, $lastName, $age, $password, $ide)
    {
        $this->ide = $ide;
        parent::__construct($firstName, $lastName, $age, $password);
    }

    public function greet()
    {
        echo("Hello world! I'm $this->firstName");
    }

    public function program()
    {
        echo("I'm programming in {$this->ide}...");
    }

}

If you were to run the application, everything would work just like it did before. Now, move to the PhpProgrammer class and comment out the program() method. If you go back again to index, you'll see the following error message:

Your page
localhost

The message tells us that the PhpProgrammer class implements the interface even though it doesn't have all of the required methods. Now, uncomment the program() method.

Meaning of interfaces

Interfaces bring many benefits to everyday programming, of which I will list a few:

Method overriding

As you already know, they allow us to choose the methods shown by the class. Along with visibility modifiers (private), interfaces are another tool used to keep proper code functionality.

Detecting interface presence

Let's put our people into an array with a few PhpProgrammer and Human instances in index.php. We'll have the instances greet in the loop. Also, if the instance is a programmer, we'll make it code. Notice how I said programmer, not PhpProgrammer because what we're going to do is have the program determine whether the instances implement our interface:

$people = array();
$people[] = new Human('Carl', 'Smith', 30, '123456');
$people[] = new PhpProgrammer('John', 'Newman', 24, 'passwordissword', 'Eclipse');
$people[] = new Human('Jack', 'Newman', 50, 'swordfish');
$people[] = new PhpProgrammer('Thomas', 'Moore', 28, 'correct horse battery staple', 'NetBeans');
$people[] = new Human('Maria', 'Newman', 32, 'justacceptmypasswordandstopshowingvalidationerrors');

foreach ($people as $human)
{
    echo($human . '<br />');
    if ($human instanceof ProgrammerInterface)
    {
        $human->program();
        echo('<br />');
    }
}
class Human
{

    public $firstName;
    public $lastName;
    public $age;
    private $tiredness = 0;
    public $id;
    private static $peopleCount = 0;
    private $password;

    public function __construct($firstName, $lastName, $age, $password)
    {
        $this->firstName = $firstName;
        $this->lastName = $lastName;
        $this->age = $age;
        self::$peopleCount++;
        $this->id = self::$peopleCount;
        $this->password = $password;
    }

    public function sleep($time)
    {
        $this->tiredness -= $time * 10;
        if ($this->tiredness < 0)
            $this->tiredness = 0;
    }

    public function run($distance)
    {
        if ($this->tiredness + $distance <= 20)
            $this->tiredness += $distance;
        else
            echo("I'm too tired.");
    }

    public function greet()
    {
        echo('Hi, my name is ' .  $this->firstName);
    }

    protected function fullName()
    {
        return $this->firstName . ' ' . $this->lastName;
    }

    public function __toString()
    {
        return $this->firstName . ' - ' . $this->id;
    }

    public static function validPassword($password)
    {
        return (mb_strlen($password) >= 5);
    }

}
interface ProgrammerInterface
{
    public function program();
}
class PhpProgrammer extends Human implements ProgrammerInterface
{

    public $ide;

    public function __construct($firstName, $lastName, $age, $password, $ide)
    {
        $this->ide = $ide;
        parent::__construct($firstName, $lastName, $age, $password);
    }

    public function greet()
    {
        echo("Hello world! I'm $this->firstName");
    }

    public function program()
    {
        echo("I'm programming in {$this->ide}...");
    }

}

Now run the application:

Your page
localhost

As a result, we printed out all of the people and when an instance is identified to be a programmer, we make it program as well. To do this, we used the instanceof operator which detects the presence of an interface.

Note: The numbers set after each person's names are their IDs, see previous lessons for details.

This approach allows us to identify whether an object in a variable contains a specific mechanism that we require. Regardless of whether there is a PhpProgrammer, JavaProgrammer or PunchedCardPro­grammer instance in the variable. All we're interested in is whether the object implements the ProgrammerInterface interface.

Determining variable type

Using the instanceof operator, we can determine an instance's variable type. We simply ask for a specific instance type in a variable using plain OOP. Without the use of the instanceof operator, we'd have to do something like declaring a HUMAN_TYPE constant in PhpProgrammer with a value of "programmer". Then, if we wanted our programmer to be a chess player as well, we'd run into issues once more. However, with instanceof all we'd have to do is implement another interface.

When identifying the presence a specified variable type, we are not limited to interfaces, we can also ask for a specific class. The code would work the same even if we set it up this way, although it would only be able to call on PhpProgrammer instances:

if ($human instanceof PhpProgrammer)

In this case, the class itself behaves just like an interface. Instanceof works even when if you were to use a class that has gone through several levels of inheritance.

Interfaces can do so much more in strongly typed languages, like Java. To be honest, I don't use them all that often in PHP. However, sometimes it's best to use them, especially when it comes to more complex class hierarchies.

Naming interfaces

Last of all, we'll go over naming interfaces. As all of you Java-heads out there may already know, PascalCase is one way to do it, as I have with all of my classes. There is, however, another conventional way of naming interfaces in PHP, which is adding the word "Interface" as a suffix.

You may also see interfaces out there with the -able suffix. For example, the DrawableInterface (something that can be drawn, i.e. forces implements the paint() method), SortableInterface, and so on.

In the next lesson, Interfaces and abstract classes in PHP, we will keep working with interfaces and will introduce you to what we call abstract classes. Today's code can be downloaded in the attachment below.


 

Did you have a problem with anything? Download the sample application below and compare it with your project, you will find the error easily.

Download

By downloading the following file, you agree to the license terms

Downloaded 29x (4.29 kB)
Application includes source codes in language PHP

 

Previous article
Solved tasks for OOP in PHP lessons 12-13
All articles in this section
Object-Oriented Programming in PHP
Skip article
(not recommended)
Interfaces and abstract classes in PHP
Article has been written for you by David Capka Hartinger
Avatar
User rating:
No one has rated this quite yet, be the first one!
The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.
Unicorn university David learned IT at the Unicorn University - a prestigious college providing education on IT and economics.
Activities