An abstract class is a class that cannot be created directly. It exists only to be extended. It can contain finished methods and abstract methods that child classes must write.
<?php
abstract class Shape
{
abstract public function area(): float;
public function describe(): string
{
return static::class . " with area " . round($this->area(), 2);
}
}
class Circle extends Shape
{
public function __construct(private float $radius) {}
public function area(): float
{
return M_PI * $this->radius ** 2;
}
}
class Rectangle extends Shape
{
public function __construct(private float $w, private float $h) {}
public function area(): float
{
return $this->w * $this->h;
}
}
echo (new Circle(2))->describe() . "\n";
echo (new Rectangle(3, 4))->describe();
Circle with area 12.57
Rectangle with area 12
abstract class Shapecannot be instantiated.abstract public function area()has no body. Every child must provide it.describe()is a normal method that all children share. It callsarea(), which each child defines in its own way.
You cannot instantiate it
<?php
abstract class Shape {}
try {
new Shape();
} catch (Error $e) {
echo $e->getMessage();
}
Cannot instantiate abstract class Shape
A child must implement all abstract methods
If a child forgets one, PHP reports a fatal error when the class is declared.
<?php
abstract class Shape
{
abstract public function area(): float;
}
class Broken extends Shape {}
Fatal error: Class Broken contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Shape::area) in /path/to/index.php on line 7
The template method pattern
An abstract class can define the steps of a process and let children fill in the details.
<?php
abstract class Report
{
public function render(): string
{
return $this->header() . "\n" . $this->body() . "\n" . $this->footer();
}
protected function header(): string
{
return "== Report ==";
}
abstract protected function body(): string;
protected function footer(): string
{
return "== End ==";
}
}
class SalesReport extends Report
{
protected function body(): string
{
return "Sales: 1200";
}
}
echo (new SalesReport())->render();
== Report ==
Sales: 1200
== End ==
Abstract class vs interface
| Abstract class | Interface | |
|---|---|---|
| Can hold code | Yes | No (only method signatures) |
| Can hold properties | Yes | No |
| A class can use | Only one | Many |
| Use when | Related classes share code and a skeleton | Unrelated classes share a contract |
The next lesson covers interfaces.
Why this matters in Laravel
Model, Controller, Command) are abstract or base classes. When you write class User extends Model, you inherit a large amount of behaviour and fill in only the parts that are yours.