Designing Elegant Solutions through Interface Magic
The topic of interfaces. An interface resembles an abstract class but there are a few differences. With the abstract class, you can create method declarations and implemented methods. Child classes can then inherit an abstract class and override or implement its methods. With an interface, you can only define the functionality. You can’t actually implement anything.
The biggest difference is that a child class can only extend one abstract class but it can implement multiple interfaces. You will hear the term contract when talking about interfaces meaning that once you implement it, you are obligated to define each method that was declared inside the interface.
Our Mammal class is a perfect example of an abstract class. There are certain methods that all mammals share, and do it the same way, so it’s a good idea to actually implement those methods there. I would argue that the Animal class makes a good candidate for an interface. Why? Because although all animals share certain similar traits, they each differ based on the animal.
https://blog.devgenius.io/php-p60-abstract-classes-e7912ee3be7c
So, you should force child classes to implement those methods. Interfaces begin with the keyword interface and the methods inside the interface are all abstract. You don’t have to use the abstract keyword. To implement the interface, you use the implements keyword, not the extends keyword.
Recap: Review the following classes from the previous article. The Animal class is the one that we’ll modify.
Since we spent a good amount of time focusing on Abstract classes in the previous article, this one should be a breeze. We’ll start off by creating a file that instantiates our GermanShepherd class and then calls our bark() and sleep() methods.
<?php
// Interfaces
require_once("GermanShepherd.php");
$gs_dog = new GermanShepherd("Brown", "Oct 10, 2015", "Brown");
$gs_dog->bark();
$gs_dog->sleep(30);
The bark() method is a method that exists inside of the GermanShepherd class. GermanShepherd extends Dog. Dog extends Mammal. Mammal extends Animal, which is where our sleep() method lives.
For the sake of simplicity, I’ve removed all other methods from our Animal class and we’re left with just the sleep() method.
<?php
class Animal {
public function sleep(int $energy_level = 100)
{
if ($energy_level < 40) {
echo "I'm sleeping";
} else {
echo "I don't want to sleep";
}
}
//...
}
The result that we’ll get when calling the code above is “Loud Barking” and “I’m sleeping” since the energy level that we passed is less than 40.
To change the Animal class into an interface, we have to replace the class keyword with the interface keyword and remove the sleep() declaration.
<?php
class Animal {
public function sleep(int $energy_level = 100);
}
If we run our code again, we’ll get our first error that states that we cannot extend our interface.
The modification that we’ll need to make is within our Mammal class, since the Mammal class currently extends our Animal class. The extends keyword can only be used for classes. To implement the Animal interface, we must use the implements keyword.
<?php
require_once("Animal.php");
abstract class Mammal implements Animal {
//...
}
If we refresh the code again, we get our next error.
We have to implement our sleep() method somewhere down the inheritance chain. We’ll implement it in our GermanShepherd class.
<?php
require_once("Dog.php");
class GermanShepherd extends Dog
{
//...
public function sleep(int $energy_level = 100)
{
if ($energy_level < 40) {
echo "I'm a sleeping German Shepherd";
} else {
echo "I'm a non-sleeping German Shepherd";
}
}
}
Now that we’ve implemented the sleep() method in our GermanShepherd class, we can refresh our code and get the following result: “Loud Barking” followed by “I’m a sleeping German Shepherd.”
That’s it for interfaces. No craziness. The only other one that I would encourage you to practice is implementing multiple interfaces. For example, let’s say that you have two additional interfaced that you also want to implement into GermanShepherd: ServiceDog and PoliceDog. The syntax would go like this.
The GermanShepherd class implements ServiceDog and PoliceDog interfaces directly and implements the Animal class contract indirectly through inheritance.
BUILDING WORLDS ON ABSTRACT CLASS PILLARS
For static class members, we don’t use the $this keyword, we use self. That and the scope resolution operator allows us to access the static properties and methods.
Designing Elegant Solutions through Interface Magic
The topic of interfaces. An interface resembles an abstract class but there are a few differences. With an interface, you can only define the functionality.
SERENADING COMPLEXITY INTO ELEGANCE WITH HARMONIOUS TRAITS
There is a fundamental problem in programming languages that support Multiple Inheritance. Traits solve that problem.