A child class extends one parent, inherits its public and protected members, and may override methods with compatible signatures; parent:: calls the overridden version. self:: binds to the class where it is written, static:: to the class actually called: late static binding.
<?php
class Product {
public function __construct(public string $title) {}
public static function create(string $title): static { return new static($title); }
public static function kindSelf(): string { return self::kind(); } // where written
public static function kindStatic(): string { return static::kind(); } // who was called
protected static function kind(): string { return 'product'; }
}
class Ebook extends Product {
public function __construct(string $title, public float $sizeMb = 2.5) {
parent::__construct($title); // run the parent's constructor
}
protected static function kind(): string { return 'ebook'; } // override
}
$e = Ebook::create('Dune'); // inherited, yet builds an Ebook
echo get_class($e), " {$e->title} {$e->sizeMb} MB | ";
echo Ebook::kindSelf(), ' vs ', Ebook::kindStatic(), "\n";Output
Ebook Dune 2.5 MB | product vs ebook
Use self:: when subclasses must not redirect a call, static:: when they should. Share behavior across unrelated classes with Interfaces and Generators's interfaces and traits or with composition (Subsection 4.9.14).