← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Interface vs Abstract Class

php PHP 5.0+ Intermediate
debt(d5/e3/b7/t5)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list phpstan and phpcs as tools — both are specialist static analysis tools, not default linters. The code patterns (abstract class with all abstract methods; interface with default method workarounds) require these tools to flag, not a compiler or basic linter.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix indicates replacing an abstract class with an interface or vice versa, which is a targeted refactor within one component. It's more than a one-line patch — implementors and call sites referencing the type may need updating — but it typically doesn't cross multiple files extensively if the hierarchy is small.

b7 Burden Structural debt — long-term weight of choosing wrong

Closest to 'strong gravitational pull' (b7). The choice of interface vs. abstract class shapes the entire class hierarchy and applies across web, cli, and queue-worker contexts. As noted in why_it_matters, it 'shapes the entire class hierarchy' — every implementor, subclass, and consumer is constrained by this decision. Locking implementors into single inheritance via an abstract class is a persistent and pervasive structural commitment.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap' (t5). The misconception is well-documented: developers conflate the two constructs, use abstract classes when interfaces suffice (locking into single inheritance), or define both but only ever use the abstract. These are documented gotchas that most PHP developers eventually learn, but the 'obvious' approach (grabbing an abstract class for shared-looking concerns) is frequently wrong.

About DEBT scoring →

Also Known As

interface vs abstract class PHP interface abstract vs interface

TL;DR

Interfaces define pure capability contracts with no state; abstract classes add shared implementation. Use interfaces for type contracts, abstract for shared behaviour.

Explanation

Choose an interface when defining a capability contract with no shared state — a class can implement multiple interfaces, enabling flexible type composition without inheritance constraints. Choose an abstract class when subclasses genuinely share implementation code or state that would be duplicated otherwise. PHP 8.0 added constructor promotion to abstract classes, making them more concise. A practical approach: start with an interface; introduce an abstract class alongside it only when you find yourself duplicating implementation across multiple implementors. Never use abstract classes solely to prevent instantiation — a private constructor on a final class is cleaner.

Diagram

flowchart LR
    subgraph Interface
        INT2[interface Printable<br/>print method - no body<br/>all methods public abstract]
        INT_USE[Multiple interfaces<br/>implements A B C]
        INT_WHEN[When: define a contract<br/>unrelated classes share behaviour]
    end
    subgraph Abstract_Class
        ABS[abstract class Shape<br/>can have concrete methods<br/>can have state properties]
        ABS_USE[Single inheritance<br/>extends only one]
        ABS_WHEN[When: shared base implementation<br/>related class hierarchy]
    end
style INT2 fill:#1f6feb,color:#fff
style ABS fill:#6e40c9,color:#fff
style INT_WHEN fill:#238636,color:#fff
style ABS_WHEN fill:#238636,color:#fff

Common Misconception

Interfaces and abstract classes serve the same purpose. Interfaces define a pure contract with no implementation and support multiple implementation. Abstract classes share implementation across subclasses but allow only single inheritance — choose based on whether shared state or implementation is needed.

Why It Matters

Interfaces define pure capability contracts; abstract classes share partial implementation. PHP supports multiple interface implementation but single inheritance — the choice shapes the entire class hierarchy.

Common Mistakes

  • Using an abstract class when an interface is sufficient — locks implementors into single inheritance.
  • Adding default method implementations to interfaces via abstract classes when PHP traits would be cleaner.
  • Defining both an interface and an abstract class implementing it but only ever using the abstract — the interface adds no value if never used independently.
  • Not considering that interfaces are more stable contracts — an abstract class's non-abstract methods can break subclasses when changed.

Code Examples

✗ Vulnerable
// Abstract class used as interface — unnecessary inheritance constraint:
abstract class Serializable {
    abstract public function serialize(): string;
    abstract public function unserialize(string $data): void;
    // No shared implementation — this should be an interface
}
// Classes that implement this must use their single inheritance slot
✓ Fixed
// Interface — pure contract, no implementation, multiple allowed
interface Notifiable {
    public function notify(string \$message): void;
}

// Abstract class — shared implementation + enforced contract
abstract class BaseNotifier {
    abstract protected function send(string \$to, string \$msg): void;

    public function notify(string \$message): void {
        \$this->log(\$message);
        \$this->send(\$this->recipient, \$message);
    }
}

// Use interface when: unrelated classes share a contract
// Use abstract when: related classes share implementation

// PHP: implements multiple interfaces, extends one abstract
class EmailNotifier extends BaseNotifier implements Notifiable, Loggable {
    protected function send(string \$to, string \$msg): void { /* SMTP */ }
}

Tags


Added 15 Mar 2026
Edited 22 Mar 2026
Views 21
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 2 pings S 1 ping S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 1 ping S
No pings yesterday
Amazonbot 8 Perplexity 3 Unknown AI 2 Google 2 Ahrefs 2 Majestic 1
crawler 17 crawler_json 1
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Low
⚡ Quick Fix
Use interfaces when you only need a contract (no shared code), abstract classes when you want to share some implementation — but favour composition over both when possible
📦 Applies To
PHP 5.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Abstract class with all abstract methods (use interface instead); interface with default methods workaround (use abstract class instead)
Auto-detectable: ✓ Yes phpstan phpcs
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: Medium Context: Class Tests: Update

✓ schema.org compliant