Both of these solve a similar problem: making sure a group of otherwise different classes all provide a certain set of methods, so code that uses them doesn't need to care which exact class it's working with.
An interface defines a set of method names a class promises to implement — it specifies what a class must be able to do, with no detail about how:
<?php
interface Payable {
public function pay($amount);
}
class CreditCard implements Payable {
public function pay($amount) {
echo "Charged $amount to credit card.";
}
}
class Cash implements Payable {
public function pay($amount) {
echo "Received $amount in cash.";
}
}
function checkout(Payable $method, $amount) {
$method->pay($amount); // works with any Payable, regardless of exact class
}
checkout(new CreditCard(), 500);
checkout(new Cash(), 500);
?>checkout() doesn't know or care whether it received a CreditCard or a Cash object — only that whatever it received honors the Payable interface. This is the practical payoff: code written once keeps working correctly even as new payment types are added later.
An abstract class is a class that can't be instantiated directly — it exists purely to be extended, and can mix fully-written methods with abstract ones (a method signature with no body, that every subclass must fill in):
<?php
abstract class Shape {
abstract public function area(); // every subclass must define this
public function describe() { // shared by every subclass, as-is
return "This shape has an area of " . $this->area();
}
}
class Circle extends Shape {
public function __construct(private $radius) {}
public function area() {
return round(pi() * $this->radius ** 2, 2);
}
}
$circle = new Circle(5);
echo $circle->describe(); // "This shape has an area of 78.54"
// new Shape(); // Error — cannot instantiate an abstract class
?>| Can include real method code? | A class can use how many? | Use when | |
|---|---|---|---|
| Interface | No (method signatures only) | Several, at once | Unrelated classes need to guarantee the same capability |
| Abstract class | Yes, mixed with abstract methods | One | Related classes should share real, common behavior |