PHP: Interface and Abstract Class
One of the most popular questions on the interview is “What is the difference in interfaces and abstract classes?”. So let’s see the difference.
Interfaces
Before getting into theory, let’s refresh in memory how an interface is defined:
An interface can contain methods and constants, but can’t contain any variables. All methods must be public and have no implementation.
Inheritance
In PHP one interface can be inherited from another by extends keyword:
One difference with classes comes with the multiple inheritance, which is available for interfaces:
Implementation
When we create an interface we declare that methods defined in it will be available in any class that implements the interface. For example, when we need to guarantee that an object accepts an array of data, we go and create an interface:
And then every class that implements this interface must have implementations for the interface methods. And the rest of our code base now knows that CsvTransformer class objects have getTransformedData method.
But a class can’t implement two interfaces that share the same function names because they have no bodies and it would cause ambiguity.
Abstract Class
An abstract class is also an interface. But the key difference here is that an abstract class provides the implementation logic. Let’s rewrite CsvTransformer class with the use of abstract class:
Now with the abstract class, we have declared a new data type in our language, called ArrayDataTransformer. This data type provides the interface of two public methods. The first one is a setter. The second will be specialized in child classes:
True Constants
When using abstract classes our constants may have variable values:
We can override and redeclare constants of a parent class in its child classes. Sometimes it may be useful, like in the previous example of an application’s persistence layer.
But if we need the real unchangeable constants, we can write them into interfaces. For example PI constant, then can’t be redeclared:
Summary
With the abstract class with define a new data type in our language, which has its own interface. In child classes, we may override this interface or implement new specializations. Abstract classes may be useful when we need to declare a new data type with its own logic implementation.
The interface provides only a public declaration of the methods. It is a guarantee for the client code that will interact with the objects that implement this interface. The client code doesn’t care about an object’s class, it’s private or protected methods. We may use interfaces when we don’t care about the concrete logic implementation and our client code only needs a special functionality, for example in dependency injection.