PHP Course : Abstract Classes vs Interfaces
TLDR; With Abstract Classes, you can define default behaviours that can be inherited by subclasses. That's not possible with interfaces. The template design pattent makes use of abstract classes. It defines default behaviour in the parent class but also abstract method that are meant to be implemented in the sub classes. You cannot do that with Interfaces, which are more suited to defining types.
An Abstract class provides a template for any sub classes.
Let's make two different Car class :
class Audi {
public function description() {
return "German car";
}
}
class Volvo {
public function description() {
return "Swedish car";
}
}
Immediately you see the repetition. You must not repeat your code over and over if you want to add feature to a Car class. You need a parent class to bind them.
Let's make a simple parent class then:
class Car {
public function brand() {
return (new ReflectionClass($this))->getShortName();
}
}
class Audi extends Car {
public function description() {
return "German car";
}
}
class Volvo extends Car {
public function description() {
return "Swedish car";
}
}
We can now do this:
$volvo = new Volvo;
$volvo->brand(); // prints "Volvo";
But this code also allows us to do this $car = new Car
and we should not be able to do that. It doesn't really make sense.
The solution : the abstract class ! Let's switch the Car class to an Abstract Class :
abstract class Car {
public function brand() {
return (new ReflectionClass($this))->getShortName();
}
}
class Audi extends Car {
public function description() {
return "German car";
}
}
class Volvo extends Car {
public function description() {
return "Swedish car";
}
}
Now you won't be able to instanciate the Car class anymore.
The purpose of the abstract is not only to be a Parent class, but also allows you to pre define methods. Sometimes with existing logic, sometimes not.
Let's update our Car abstract class
abstract class Car {
public function brand() {
return (new ReflectionClass($this))->getShortName();
}
public function logo() {
// we can write some default logic here
return strtolower($this->brand()) . '.png';
}
abstract public function description();
}
class Audi extends Car {
public function logo() {
// we overwrite this method from the abstract class
return 'custom-audi-logo.svg';
}
public function description() {
return "German car";
}
}
class Volvo extends Car {
public function description() {
return "Swedish car";
}
}
Interfaces simply does not let you write any default logic. The same example with Interface would be like this:
Interface Car {
public function brand(): string;
public function logo(): string;
public function description(): string;
}
class Audi extends Car {
public function brand() {
return 'Audi';
}
public function logo() {
return 'custom-audi-logo.svg';
}
public function description() {
return "German car";
}
}
For more information about interfaces you can read my course on Interface Segregation.
I consider myself as an IT Business Artisan. Or Consultant CTO. I'm a self-taught Web Developper, coach and teacher. My main work is helping and guiding digital startups.
more about meBTC
bc1qgw9a8hyqqwvcls9ln7vhql4mad0qkveutr2td7
ETH
0x3A720717Da03dB6f3c4a4Ff08BC64100205A79d0
2025 © My Dynamic Production SRL All rights Reserved.