I’m learning about classes in PHP. When I heard that multiple inheritance was not allowed, I was confused, because I thought that class B could extend class A and that was it. Which didn’t make sense to me, because what good would that be–one inheritance?
But then I found this tidbit in the PHP manual:
Just a quick note to make things more clear : while multiple inheritance is not allowed, several levels of single inheritance* ARE ALLOWED indeed.
So the question is, what is the difference between single inheritance and multiple inheritance? I understand multiple levels of single inheritance, because that’s the way I’ve always thought of inheritance… so what have I been missing in regards to multiple inheritance? And why wouldn’t PHP have this?
Multiple inheritance is pretty messy and complicated stuff. It’s basically so you can inherit not from one parent, but from two or more.
So you might have a class called TransportBoat that inherits from class Boat and from class Transporter. This can very quickly turn out into a fantasticular mess, which is why C# (and java too, I think) supports an alternate version of multiple inheritance called Interfaces. I don’t know what status multiple inheritance and Interfaces have in PHP 5.
Interfaces is basically the same thing as multiple inheritance, with the difference that an Interface never ever contains any code - i.e. it just defines WHAT methods and members a class that implements the interface should have, not how they should work. Essentially, they work just like an abstract class (PHP has those, right?)
So, essentially, inheritance is to be used for is-a relationships, while Interfaces is used for implementing. So, class car is-a (inherits) class vehicle but it might implement the CanBeBoughtWithABigLoan Interface (this Interface might also be implemented by a House)
First of all… HI! OK, I’m new to sitepoint and should perhaps lie low for a while, but… I may be totally off the scale here, but if you never try, you never learn…
Now, if the CanBeBoughtWithABigLoan interface acts exactly the same no matter where it is implemented, that means that the implementation has to exist in many places at the same time and that is something I don’t want.
If CanBeBoughtWithABigLoan suddenly changes its implementation… Now, just how many classes do I have that implement that Interface? Not to mention that CanBeBoughtWithABigLoan extends interface CanBeBoughtWithALoan! Now, let’s see… We have GardenTools, HouseHoldAppliances, StocksSharesAndBonds, KiddiesBraces… Marriage had better implement PreNup or I’m ruined!
OK, so I could put the CanBeBoughtWithABigLoan implementation in some base-class but I don’t want a base-class bloated with functionality I may not want to use or I might much rather implement PayInCash!
PHP isn’t a (pre-)compiling language and wasting processor time on parsing stuff I may not need isn’t my idea of fun. It’s bad enough as it is with moi happily hacking along!
I can’t include or require inside a class body, so including simple functions into the body of some other class is out of the question. That would actually make it a lot simpler for me because that would allow me to keep the code I want accessible in a sparate file and I could include it where I want.
I could use __autoload() and parse for includes myself…
I’m not a C++ person. I’ve done a little non-com work in C++ for fun. I’m more into Java (certainly not an expert) and PHP 5. I agree, multiple inheritance can be really messy but I still miss it.
I’m trying to marry some simple XML functionality with a budding generic data access class library and I do miss MI. I have a XMLObject class whose functionality I want to marry with a DataSet class and a Row class to make them both return their data in XML.
Oops! Forgot to tell why, didn’t I? I’m more into XML (,XSL/T) and CSS than creating (table-based) HTML-pages and that’s why I want the XML without having to bend over backwards to get it. I want simple queries to any datasource to be able to return XML via the __toString() in PHP 5. I’m slowly getting there but want MI!
Someone pleeeease tell why I really don’t need MI!
“Is a” implies that every conceptual behaviour in one class matches the conceptual behaviour in another. Genuine “is a” relationships are actually uncommon and in fact inheritance is often overused. It is incredibly useful for variations on a theme (such as strategies) because of the code it saves, but the slightest deviation from true "is a " causes confusion to build up very quickly. In fact it is usually better to avoid inheritance until similar classes emerge and common code can be factored into the superclass.
Multiple inheritance assumes that behaviours in a class can be factored out completely. To need MI you would need two or more behaviours with two or more variations that can be combined orthogonally. So unusual is this situation that I cannot even think of an example to illustrate this.
Inheritance actually isn’t very useful. You will save maybe 15- 10% of the coding with inheritance even on a good day and on a bad day you will get it wrong and have to tease it all apart again. The real win is polymorphism. If a function works on a limited set of methods on an object (an interface) then everytime you create a class with these methods your function gains a new use. This is a geometric gain of productivity.
Interfaces have nothing to do with MI as far as I can see. Interfaces are about adding documentation and safety guarantees to polymorphism. They define partial types and a class may implement several interfaces simply by having the methods. I think the confusion arises because C++ enforced partial types by using the only type mechanism it had - inheritance. To have multiple interfaces that means it had to have MI.
You can avoid inheritance simply by wrapping and chaining another class rather than extending it and you can do this to avoid MI as well. You may find an occasion where MI was useful (I have wished for it on occasion), but these cases will be rare. It is much more likely that what you think is an “is a” is probably a “has a”.