Skip to content
Inheritance and Interfaces
step 1/7

Reading — step 1 of 7

Learn

~3 min readClasses, Inheritance, Errors

PHP supports single class inheritance and multiple interface implementation. The PHP manual covers these as fundamental OOP building blocks. Modern frameworks (Laravel, Symfony) use them extensively.

Class inheritance

class Animal {
    public function __construct(public string $name) {}
    
    public function speak(): string {
        return "{$this->name} makes a sound";
    }
}

class Dog extends Animal {
    public function speak(): string {
        return "{$this->name} barks";
    }
}

$rex = new Dog('Rex');
echo $rex->speak();    // Rex barks
  • extends for class inheritance
  • Override a method by redefining it (no special keyword needed in PHP)
  • parent::method() calls the parent's version
class Puppy extends Dog {
    public function speak(): string {
        return parent::speak() . " (puppy voice)";
    }
}

abstract — must override

abstract class Shape {
    abstract public function area(): float;
    
    public function describe(): string {
        return "Shape with area " . $this->area();
    }
}

class Circle extends Shape {
    public function __construct(public float $radius) {}
    
    public function area(): float {
        return M_PI * $this->radius ** 2;
    }
}
  • abstract class can't be instantiated
  • abstract method has no body — subclasses must implement
  • Can mix concrete methods (with bodies) and abstract methods

final — prevent further inheritance

final class FinalDog extends Dog {
    // ...
}

// class Puppy extends FinalDog {}     // ERROR — final

class Cat extends Animal {
    final public function speak(): string {
        return "meow";
    }
}

// class BlackCat extends Cat {
//     public function speak(): string { ... }    // ERROR — speak is final
// }

final on a class prevents subclassing. final on a method prevents overriding.

Interfaces

interface Greetable {
    public function greet(): string;
}

interface Loggable {
    public function log(): void;
}

class User implements Greetable, Loggable {
    public function __construct(public string $name) {}
    
    public function greet(): string {
        return "Hi, I'm {$this->name}";
    }
    
    public function log(): void {
        echo "[User] {$this->name}";
    }
}
  • implements for interfaces (multiple, comma-separated)
  • Interface methods are implicitly abstract — no body in the interface
  • All interface methods must be public
  • Modern interfaces should declare return types and parameter types

A class can implement multiple interfaces. PHP doesn't allow multiple class inheritance.

Traits — code reuse without inheritance

For sharing implementation across unrelated classes:

trait Timestamps {
    private \DateTimeImmutable $createdAt;
    private ?\DateTimeImmutable $updatedAt = null;
    
    public function touch(): void {
        $this->updatedAt = new \DateTimeImmutable();
    }
}

class Article {
    use Timestamps;
    
    public function __construct(public string $title) {
        $this->createdAt = new \DateTimeImmutable();
    }
}

use TraitName injects the trait's methods/properties into the class. Note: PHP Intermediate covers traits in detail — this is a brief intro.

Late static binding — static::

class Animal {
    public static function create(): static {
        return new static();      // creates the actual called class, not Animal
    }
}

class Dog extends Animal {}

$d = Dog::create();             // Dog instance, not Animal
echo get_class($d);              // "Dog"

static:: resolves at runtime to the calling class. Useful for factory methods that should respect inheritance.

Common mistakes

  • extends for interfaces — interfaces use extends for INTERFACE inheritance (interface A extends B), but classes use implements for interfaces.
  • Private methods in parent invisible to subclass — protected makes them accessible.
  • Forgetting parent::__construct(...) in subclass constructor — parent's setup doesn't run.
  • Using extends when interface fits better — favor composition / interfaces over deep inheritance.
  • Mixing inheritance and traits with conflicting names — must resolve with insteadof.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…