Inheritance
Learn how PHP classes can extend one another to share and override behavior, modeling real "is-a" relationships.
Introduction
Imagine you already have a `Vehicle` class with common properties like speed and fuel, and now you need a `Car` and a `Motorcycle` that share all of that but each add their own extra behavior. Copy-pasting the `Vehicle` code into both would work, but any future fix would need to be repeated in three places. Inheritance solves this by letting one class reuse and extend another.
This lesson covers how to create a child class with `extends`, how to override inherited methods, how to still call the parent's version of a method with `parent::`, and an important limit: PHP only allows a class to extend one parent.
- How to use extends to create a child class from a parent class.
- How to override a method to give a subclass its own behavior.
- How to call the parent's method or constructor explicitly with parent::.
- Why PHP only supports single inheritance, and what that means going forward.
- Why inheritance is used to model "is-a" relationships.
Extending a Class
A child class (also called a subclass) is created with the `extends` keyword. It automatically gains every public and protected property and method from its parent class, and can add new ones of its own.
<?php
class Animal
{
protected string $name;
public function __construct(string $name)
{
$this->name = $name;
}
public function eat(): void
{
echo "{$this->name} is eating.\n";
}
}
class Dog extends Animal
{
public function bark(): void
{
echo "{$this->name} says Woof!\n";
}
}
$rex = new Dog("Rex");
$rex->eat(); // inherited from Animal
$rex->bark(); // defined in DogRex is eating.
Rex says Woof!`Dog` never redefines `eat()` or the constructor, yet `$rex` has full access to both because `Dog extends Animal`. The `protected` property `$name` is also inherited and usable inside `Dog`, since protected members are visible to subclasses.
Overriding Methods
A subclass can redefine a method it inherits, replacing the parent's implementation with its own. This is called method overriding, and it is one of the most powerful features inheritance provides.
<?php
class Animal
{
protected string $name;
public function __construct(string $name)
{
$this->name = $name;
}
public function makeSound(): void
{
echo "{$this->name} makes a generic animal sound.\n";
}
}
class Cat extends Animal
{
public function makeSound(): void
{
echo "{$this->name} says Meow!\n";
}
}
$generic = new Animal("Creature");
$cat = new Cat("Whiskers");
$generic->makeSound();
$cat->makeSound();Creature makes a generic animal sound.
Whiskers says Meow!`Cat` provides its own `makeSound()` with the exact same name and signature as `Animal`'s, so calling it on a `Cat` object runs the overridden version instead of the parent's.
Calling the Parent with parent::
Sometimes you want to override a method but still run the parent's original logic first, adding to it rather than fully replacing it. The `parent::` keyword lets a subclass explicitly call the parent class's version of a method or constructor.
<?php
class Employee
{
protected string $name;
protected float $baseSalary;
public function __construct(string $name, float $baseSalary)
{
$this->name = $name;
$this->baseSalary = $baseSalary;
}
public function describe(): string
{
return "{$this->name} earns \${$this->baseSalary}";
}
}
class Manager extends Employee
{
private float $bonus;
public function __construct(string $name, float $baseSalary, float $bonus)
{
parent::__construct($name, $baseSalary); // reuse the parent constructor
$this->bonus = $bonus;
}
public function describe(): string
{
$base = parent::describe(); // reuse the parent method, then add to it
return $base . " plus a \${$this->bonus} bonus";
}
}
$m = new Manager("Jordan", 60000, 5000);
echo $m->describe() . "\n";Jordan earns $60000 plus a $5000 bonus`Manager::__construct()` calls `parent::__construct()` to handle the shared setup, then adds its own. `Manager::describe()` does the same with the string it builds, extending the parent's output instead of duplicating it.
If a subclass defines its own constructor, PHP no longer calls the parent constructor automatically — you must call parent::__construct() yourself if you still need that setup logic to run.
Single Inheritance in PHP
PHP only supports single inheritance: a class can extend exactly one parent class, never more than one. Writing `class Foo extends Bar, Baz` is a syntax error — PHP simply does not allow it.
Unlike some languages, PHP classes cannot inherit from multiple parent classes at once. If you need to share behavior across classes that are not naturally related by an "is-a" hierarchy, PHP offers Traits for that purpose — a separate mechanism covered in an upcoming lesson.
This restriction keeps class hierarchies simple and predictable: given any class, there is exactly one chain of parents to trace, with no ambiguity about which parent a method or property came from.
Why Inheritance Models "Is-A"
Inheritance should be used when the relationship between two classes is genuinely "is-a": a `Dog` is an `Animal`, a `Manager` is an `Employee`, a `Car` is a `Vehicle`. If that sentence does not sound natural, inheritance is probably the wrong tool.
Before writing "class B extends A", say the sentence "B is a A" out loud. If it makes sense (a Cat is an Animal), inheritance fits. If it does not (a Car is an Engine would be wrong — a Car has an Engine), you likely want composition instead: storing an instance of one class as a property of another.
Common Mistakes
- Trying to extend more than one class at once — PHP allows only a single parent.
- Defining a constructor in a subclass and forgetting to call parent::__construct() when the parent's setup is still needed.
- Using inheritance for relationships that are not really "is-a", leading to awkward, unnatural hierarchies.
- Overriding a method and accidentally changing its meaning so much that it breaks code relying on the parent's behavior.
Best Practices
- Only reach for inheritance when the "is-a" relationship genuinely holds.
- Call parent::__construct() explicitly whenever a subclass constructor still needs the parent's setup logic.
- Keep inheritance chains shallow — two or three levels deep at most — to keep code easy to follow.
- Prefer composition over inheritance when classes share behavior but are not truly related by an "is-a" relationship.
Frequently Asked Questions
Can a subclass access private properties of its parent?
No. Private members are visible only within the exact class that defines them. Use protected instead if a subclass needs direct access.
What happens if I do not define a constructor in the subclass?
PHP automatically uses the parent's constructor. It is only when you define your own constructor in the subclass that you must explicitly call parent::__construct() to still run the parent's setup.
Can I call parent:: for any method, not just the constructor?
Yes. parent::methodName() works for any method the parent defines, not only __construct().
What do I use if I need to share code between unrelated classes?
Traits, covered in a later lesson, let you share methods across classes that do not fit a single-parent inheritance hierarchy.
Key Takeaways
- extends creates a child class that inherits its parent's public and protected members.
- A subclass can override an inherited method to provide its own behavior.
- parent:: lets a subclass explicitly call the parent's version of a method or constructor.
- PHP only supports single inheritance — a class can extend exactly one parent.
- Inheritance should model a genuine "is-a" relationship between classes.
Summary
Inheritance lets you build a hierarchy of classes that share common behavior while each adding or overriding their own. Using extends, method overriding, and parent::, you can reuse code confidently, and PHP's single-inheritance rule keeps that hierarchy simple to reason about.
- You can create a subclass with extends.
- You can override an inherited method.
- You can call a parent method or constructor with parent::.
- You understand PHP's single-inheritance limitation and why "is-a" matters.