Interface vs Abstract Class
Part of the Object Oriented Programming section of Coddy's PHP journey — lesson 30 of 91.
Now that you've learned both interfaces and abstract classes, let's clarify when to use each. While they may seem similar, they serve different purposes and have distinct capabilities.
| Feature | Interface | Abstract Class |
|---|---|---|
| Methods | Only method signatures | Both abstract and concrete methods |
| Properties | Only constants | Can have properties |
| Multiple inheritance | A class can implement many | A class can extend only one |
| Constructor | Not allowed | Can have constructor |
Use an interface when you want to define a contract that unrelated classes can fulfill. For example, both a Printer and a Logger might implement a Writable interface, even though they share no common ancestor.
Use an abstract class when you have related classes that share common code. If your Dog and Cat classes both need the same eat() method implementation, an abstract Animal class lets you write that code once.
You can also combine both approaches. A class can extend an abstract class while implementing multiple interfaces:
<?php
abstract class Animal {
protected $name;
public function eat() {
return $this->name . " is eating";
}
}
interface Swimmable {
public function swim();
}
class Duck extends Animal implements Swimmable {
public function __construct($name) {
$this->name = $name;
}
public function swim() {
return $this->name . " is swimming";
}
}
Key Point: Choose interfaces for defining capabilities across unrelated classes. Choose abstract classes when you need to share code among related classes.
Challenge
EasyLet's build a vehicle system that demonstrates when to use an abstract class versus an interface — and how to combine both approaches effectively.
You'll create a system where vehicles share common properties through inheritance, but can also gain additional capabilities through interfaces. This mirrors real-world design decisions: a car "is a" vehicle (inheritance), but it also "has the capability" to be refuelable (interface).
Organize your code across four files:
Refuelable.php— Define aRefuelableinterface with a single method signature:refuel($amount). This capability can apply to any class that needs refueling, regardless of its inheritance hierarchy.Vehicle.php— Define an abstractVehicleclass that provides shared functionality for all vehicles. It should have a protected$brandproperty and a protected$fuelLevelproperty (starting at 0). The constructor accepts the brand name. Include a concretegetBrand()method that returns the brand, a concretegetFuelLevel()method that returns the current fuel level, and an abstractdrive()method that child classes must implement.Car.php— Create aCarclass that extendsVehicleand implementsRefuelable. Include both required files at the top. The constructor accepts the brand and passes it to the parent constructor. Implementdrive()to return"[brand] car is driving". Implementrefuel($amount)to add the amount to the fuel level and return"[brand] refueled to [fuelLevel] liters".main.php— Include the Car file. You'll receive two inputs: a brand name and a fuel amount (convert to integer). Create aCarwith the brand. Print the result ofdrive()on the first line, then print the result ofrefuel()with the fuel amount on the second line.
This challenge illustrates the key distinction: the abstract Vehicle class shares code and establishes an "is-a" relationship, while the Refuelable interface adds a capability that could apply to other unrelated classes (like a generator or a boat) without requiring them to be vehicles.
Cheat sheet
Interfaces and abstract classes serve different purposes:
| Feature | Interface | Abstract Class |
|---|---|---|
| Methods | Only method signatures | Both abstract and concrete methods |
| Properties | Only constants | Can have properties |
| Multiple inheritance | A class can implement many | A class can extend only one |
| Constructor | Not allowed | Can have constructor |
Use an interface to define a contract for unrelated classes. Use an abstract class to share common code among related classes.
A class can extend an abstract class while implementing multiple interfaces:
<?php
abstract class Animal {
protected $name;
public function eat() {
return $this->name . " is eating";
}
}
interface Swimmable {
public function swim();
}
class Duck extends Animal implements Swimmable {
public function __construct($name) {
$this->name = $name;
}
public function swim() {
return $this->name . " is swimming";
}
}
Try it yourself
<?php
require_once 'Car.php';
// Read input
$brand = trim(fgets(STDIN));
$fuelAmount = intval(trim(fgets(STDIN)));
// TODO: Create a Car with the brand
// TODO: Print the result of drive() on the first line
// TODO: Print the result of refuel() with the fuel amount on the second line
?>This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe $this KeywordMethodsPropertiesConstructor (__construct)Destructor (__destruct)Recap - Simple Calculator4Inheritance
Basic InheritanceThe parent:: KeywordMethod OverridingThe final KeywordAbstract ClassesRecap - Employee Hierarchy7Encapsulation
Public, Protected, PrivateAccess Modifiers in DepthGetters and SettersInformation HidingConstructor Promotion (8.0)Recap - Student Records System2Namespaces & Autoloading
Introduction to NamespacesThe use KeywordPSR-4 Autoloading StandardComposer AutoloaderRecap - Organized Project5Interfaces & Contracts
Introduction to InterfacesImplementing InterfacesMultiple Interface ImplementInterface vs Abstract ClassType Hinting with InterfacesRecap - Shape Calculator8Magic Methods
Magic Methods Introduction__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Object Cloning__serialize & __unserializeRecap - Custom Collection11Type System & Error Handling
Type DeclarationsNullable TypesUnion & Intersection TypesException ClassesCustom Exception HierarchyTry, Catch, FinallyRecap - Form Validator14Project: Library Management
Project OverviewBook and User Classes3Class Properties
Instance vs Static PropertiesConstants in ClassesStatic Methods & PropertiesPrivate & Protected PropertiesReadonly Properties (PHP 8.1)Recap - Bank Account Manager6Polymorphism
Method Overriding RevisitedPolymorphism via InterfacesType Hinting & Union TypesLate Static BindingRecap - Payment Processor9Traits
Introduction to TraitsUsing Multiple TraitsTrait Conflict ResolutionAbstract Methods in TraitsTraits vs Inheritance12Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternObserver PatternStrategy Pattern