Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Inheritance in PHP

I'm looking for a good, clean way to go around the fact that PHP5 still doesn't support multiple inheritance. Here's the class hierarchy:

Message
-- TextMessage
-------- InvitationTextMessage
-- EmailMessage
-------- InvitationEmailMessage

The two types of Invitation* classes have a lot in common; i'd love to have a common parent class, Invitation, that they both would inherit from. Unfortunately, they also have a lot in common with their current ancestors... TextMessage and EmailMessage. Classical desire for multiple inheritance here.

What's the most light-weight approach to solve the issue?

Thanks!

like image 747
Alex Weinstein Avatar asked Sep 18 '08 08:09

Alex Weinstein


People also ask

What is multiple inheritance in PHP?

Multiple Inheritance is the property of the Object Oriented Programming languages in which child class or sub class can inherit the properties of the multiple parent classes or super classes.

Why multiple inheritance is not allowed in PHP?

Multiple inheritance actually suffers from the Diamond Problem. The “diamond problem” (sometimes referred to as the “deadly diamond of death”) is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C.

What is multiple inheritance explain with example?

Multiple Inheritance is a feature of C++ where a class can inherit from more than one classes. The constructors of inherited classes are called in the same order in which they are inherited. For example, in the following program, B's constructor is called before A's constructor.

How many types of inheritance are there in PHP?

It supports the concept of hierarchical classification. Inheritance has three types, single, multiple and multilevel Inheritance. PHP supports only single inheritance, where only one class can be derived from single parent class.


2 Answers

Alex, most of the times you need multiple inheritance is a signal your object structure is somewhat incorrect. In situation you outlined I see you have class responsibility simply too broad. If Message is part of application business model, it should not take care about rendering output. Instead, you could split responsibility and use MessageDispatcher that sends the Message passed using text or html backend. I don't know your code, but let me simulate it this way:

$m = new Message(); $m->type = 'text/html'; $m->from = 'John Doe <[email protected]>'; $m->to = 'Random Hacker <[email protected]>'; $m->subject = 'Invitation email'; $m->importBody('invitation.html');  $d = new MessageDispatcher(); $d->dispatch($m); 

This way you can add some specialisation to Message class:

$htmlIM = new InvitationHTMLMessage(); // html type, subject and body configuration in constructor $textIM = new InvitationTextMessage(); // text type, subject and body configuration in constructor  $d = new MessageDispatcher(); $d->dispatch($htmlIM); $d->dispatch($textIM); 

Note that MessageDispatcher would make a decision whether to send as HTML or plain text depending on type property in Message object passed.

// in MessageDispatcher class public function dispatch(Message $m) {     if ($m->type == 'text/plain') {         $this->sendAsText($m);     } elseif ($m->type == 'text/html') {         $this->sendAsHTML($m);     } else {         throw new Exception("MIME type {$m->type} not supported");     } } 

To sum it up, responsibility is split between two classes. Message configuration is done in InvitationHTMLMessage/InvitationTextMessage class, and sending algorithm is delegated to dispatcher. This is called Strategy Pattern, you can read more on it here.

like image 55
Michał Niedźwiedzki Avatar answered Oct 07 '22 08:10

Michał Niedźwiedzki


Maybe you can replace an 'is-a' relation with a 'has-a' relation? An Invitation might have a Message, but it does not necessarily need to 'is-a' message. An Invitation f.e. might be confirmed, which does not go well together with the Message model.

Search for 'composition vs. inheritance' if you need to know more about that.

like image 32
Matthias Kestenholz Avatar answered Oct 07 '22 06:10

Matthias Kestenholz