Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Interfaces and abstract classes

Sometimes what matters is not how an object is built but what it can do. An interface describes exactly that: a list of methods a class must have.

Interfaces

An interface lists methods without bodies. A class that implements it must declare all of them:

<?php
 
interface Shape
{
    public function area(): float;
}
 
class Rectangle implements Shape
{
    public function __construct(private float $width, private float $height) {}
 
    public function area(): float
    {
        return $this->width * $this->height;
    }
}
 
class Circle implements Shape
{
    public function __construct(private float $radius) {}
 
    public function area(): float
    {
        return 3.14159 * $this->radius ** 2;
    }
}
 
function printArea(Shape $shape): void
{
    echo $shape->area(), "\n";
}
 
printArea(new Rectangle(2, 3)); // 6
printArea(new Circle(1));       // 3.14159

The printArea() function accepts any object that implements Shape. It does not care whether it is a rectangle or a circle — having an area() method is enough.

Why it matters

An interface is a contract between parts of a program. When you add a new shape you do not change printArea(): implementing the interface is enough. That makes a program easier to extend and to test.

Built-in interfaces

PHP ships with interfaces that connect your classes to language features. For example, Countable lets you pass an object to the count() function:

<?php
 
class Cart implements Countable
{
    private array $items = [];
 
    public function add(string $item): void
    {
        $this->items[] = $item;
    }
 
    public function count(): int
    {
        return count($this->items);
    }
}
 
$cart = new Cart();
$cart->add('tea');
$cart->add('coffee');
 
echo count($cart); // 2

A class may implement several interfaces at once — list them separated by commas.

Abstract classes

An abstract class is a template: some of its methods are complete, while others are only declared and must be provided by child classes:

<?php
 
abstract class Report
{
    abstract protected function body(): string;
 
    public function render(): string
    {
        return "=== Report ===\n" . $this->body();
    }
}
 
class SalesReport extends Report
{
    protected function body(): string
    {
        return 'Sold: 42';
    }
}
 
echo (new SalesReport())->render();

The shared part — the header — is written once, and each report defines its own content.

Which one to choose

InterfaceAbstract class
Ready-made codeNoPossible
PropertiesNoYes
How many you can useSeveralOne

If you only need to describe what an object can do, use an interface. If the children share code, use an abstract class.

A common mistake

You cannot create an object of an interface or an abstract class: new Shape() throws an error. Objects are created only from regular classes that implement them.

Thanks for reading!

Donate to the site — we work hard for you.