Concrete class vs abstract class — what 'concrete' means in OOP vocabulary
Definition
A concrete class is a class that can be instantiated directly — it provides a complete implementation of every method it declares or inherits. An abstract class is a class declared with the abstract keyword that cannot be instantiated and may contain one or more abstract methods (method signatures with no body) that subclasses are required to implement. The word "concrete" in OOP vocabulary specifically means "instantiable and fully implemented," not simply "real" or "specific."
In Practice
<?php
// Abstract class: defines structure and shared logic; cannot be instantiated
abstract class Report
{
// Concrete method — shared logic all subclasses inherit
public function generate(): string
{
$data = $this->fetchData(); // calls the subclass method
return $this->format($data); // calls the subclass method
}
// Abstract methods — subclasses MUST implement these
abstract protected function fetchData(): array;
abstract protected function format(array $data): string;
}
// Concrete class — implements all abstract methods; can be instantiated
class SalesReport extends Report
{
protected function fetchData(): array
{
return DB::table('orders')->select('total')->get()->toArray();
}
protected function format(array $data): string
{
return implode("\n", array_column($data, 'total'));
}
}
// This works:
$report = new SalesReport();
echo $report->generate();
// This fails with a fatal error:
// $report = new Report(); // Cannot instantiate abstract class Report
// The container can resolve concrete classes without explicit bindings:
$report = app()->make(SalesReport::class); // works
// $report = app()->make(Report::class); // fails — abstract classAbstract classes are the PHP mechanism behind the Template Method design pattern: the abstract class defines the skeleton of an algorithm in its concrete generate() method, and the abstract methods are the "steps" the subclass fills in. Laravel uses this pattern extensively — Illuminate\Auth\Guard is abstract, Illuminate\Database\Eloquent\Model has abstract-like extension points via methods you override.
In Context
In interviews, the question "what's the difference between an abstract class and an interface?" is extremely common. The precise answer: an abstract class can have concrete methods (shared implementation), constructor logic, and properties — it enforces an inheritance relationship. An interface only specifies method signatures, allows multiple implementation (a class can implement many interfaces but only extend one class), and has no implementation at all (in PHP 8, interfaces cannot have properties or method bodies, except for constants).
A common misconception is that "abstract" means "incomplete." Abstract classes are architecturally complete — they just deliberately leave certain extension points open. The abstract methods are not missing implementations; they are intentional gaps that subclasses must fill.
Related terms: "interface" achieves a similar goal (enforcing a method signature) without forcing inheritance; prefer interfaces when you only need to specify a capability. "Concrete" appears frequently in DI discussions — when a container binding maps an interface (abstract) to an EloquentUserRepository (concrete), that pairing is the essence of the dependency inversion principle.