Multiple Class Inheritance
Multiple Class Inheritance
PHP does not support multiple inheritance, meaning a class can only extend a single parent class. Hazaar provides a utility class called Hazaar\Util\Extender that simulates multiple inheritance, allowing your classes to inherit properties and methods from multiple other classes.
This is different from PHP Traits, which require code to be defined specifically as a Trait. The Extender class allows you to extend multiple standard PHP classes without modifying them.
Info
The Extender class honors private, protected, and public member visibility rules, providing a robust simulation of inheritance.
Understanding Multiple Inheritance
Imagine you have a Story class and a Book class:
class Story {
protected string $title;
protected string $topic;
public function __construct(string $title = '', string $topic = '') {
$this->title = $title;
$this->topic = $topic;
}
public function getSummary(): string {
return $this->title . ', a story about ' . $this->topic;
}
}
class Book {
protected int $isbn = 0;
public function setISBN(int $isbn): void {
$this->isbn = $isbn;
}
public function getISBN(): int {
return $this->isbn;
}
}A Novel should logically be both a Story and a Book. In standard PHP, you cannot write class Novel extends Story, Book.
Using Hazaar\Util\Extender, you can achieve this behavior dynamically.
Using the Extender
To use multiple inheritance:
- Extend your class from
Hazaar\Util\Extender. - Call
->extend()in your constructor for each class you want to inherit from.
use Hazaar\Util\Extender;
class Novel extends Extender {
public function __construct() {
$this->extend(Story::class);
$this->extend(Book::class);
}
}
$myNovel = new Novel();
$myNovel->setISBN(1234567890);
echo $myNovel->getISBN(); // Outputs: 1234567890When methods like setISBN() or getISBN() are called on the Novel instance, the Extender class dynamically routes these calls to the appropriate underlying object (in this case, an instance of Book).
Passing Arguments to Constructors
You can pass arguments to the constructors of the extended classes by adding them as additional parameters to the extend() method.
class AB extends \Hazaar\Util\Extender {
public function __construct() {
// Extends Class A and passes 'Hello, World' to A's constructor
$this->extend(A::class, 'Hello, World');
}
}Method Resolution Order
The order in which you call extend() matters. If multiple extended classes have a method with the same name, the method from the class extended first will be used.
class A {
public function getText() { return 'Class A'; }
}
class B {
public function getText() { return 'Class B'; }
}
class AB extends \Hazaar\Util\Extender {
public function __construct() {
$this->extend(A::class);
$this->extend(B::class);
}
}
$ab = new AB();
echo $ab->getText(); // Outputs: Class AMember Accessibility
The Extender class replicates standard PHP visibility rules:
- Public members are accessible from everywhere.
- Protected members are accessible only within the class hierarchy.
- Private members are accessible only within the class that defined them.
This ensures that your extended classes behave as expected when interacting with property and method visibility.
Info
Abstract classes can also be extended. The Extender automatically creates a concrete wrapper class internally to allow instantiation.