The lack of multiple inheritance, or at least some form of mixins makes any language broken in my opinion.
Take .NET for example. No multiple inheritance. The detractors say "just use interfaces". Sounds good, except for when it's not.
Here's my example that chaps my butt:
Class Part Class CartItem Inherits Part Class CartGiftCert Inherits CartItem
Doing good so far. A cart item is a part plus some extra functionality. A cart gift cert is a cart item plus some extra gift cert information. Single inheritance. Everyone is happy right?
Class OrderItem Inherits CartItem Class OrderGiftCert Inherits CartGiftCert
Now we're screwed. The order item acts like a cart item plus some order specific data. Fine. Now the OrderGiftCert has a hard choice to make. Do I inherit from CartGiftCert to get all of the good gift cert data/logic, missing out on the OrderItem specifics because I can't inherit from that too? Or does OrderGiftCert inherit from OrderItem, and miss out on all the data/logic from CartGiftCert? All we need is
Class OrderGiftCert Inherits OrderItem, CartGiftCert
"Make an interface" you hear. Great. I can make an IGiftCertItem interface, or an IOrderItem interface. In either case, now I have to implement the another class to house the logic behind those interfaces for reuse to people don't have to duplicate code. To make matters worse, everyone still has to waste time writing code to map properties/methods in/out of the implementation classes.
All problems that could just be solved with multiple inheritance. Interfaces have their place and this isn't one of them.
So, I could suck a heap of code out of the CartItem subclasses into global modules, but then you something out there that doesn't make sense all on its own.
Hey, let's just make a GiftCert that Inherits Part...but then CartGiftCert and OrderGiftCert could inherit that...but way, then they couldn't inherit CartItem and OrderItem.
I like the framework. I like the tools, but stuff like this just irks me. If Perl can do it, why can't you you stupid framework.
/me stabs .NETThe answer is because they, like the Java camp, have declared multiple inheritance bad. The reasoned that the work arounds weren't good enough to solve the diamond pattern in every case or they wanted to make things more "simple".
I would not agree that lack of it makes the language broken.
Re:Different mindsets?
Stevan on 2007-05-25T21:07:02
I suspect that too much (ab)use of MI in C++ land might have lead to the descision as well. Although it is worth pointing out that it is much more difficult to handle MI sanely when you have a class system which handles your instance variables for you. Throw in virtual methods and object upcasting and you have a real nightmare trying to determine which object slot you should write too at any given moment (this is especially true if you want to agressively optimize anything). However, this does not mean that the situation is totally hopeless, Eiffel does pretty sane MI (although it does this by restricting what you can do), and the C3 MRO (see Class::C3 on CPAN) which came out of the Dylan language goes a long way to make MI sane.
And last but not least, objects in
- Stevan.NET are not meant to be cutting edge stuff, but kind of a "C# as the lowest common denominator" approach instead. Hopefully the new dynamic language on .NET push (IronPython and IronRuby) will bring some improvements. Re:Different mindsets?
jk2addict on 2007-05-26T00:37:15
I would consider anytime you have to write an interface and an implementation class and glue that into multiple other classes just to work around the lack of MI as broken. As a tanget, the.NET 3.5 Orcas stuff adds "method extensions", which is basically the ability to inject methods into any type, which in most cases, can fix the lack of MI. 3.5 is also picking up initializer, which finnally does things like: automatically assign the values to the properties without writing all that crap out manually.new Person(){Prop1="Val";Prop2=3;Prop3=new OtherClass(){OProp1=34}}
Re:Inheritance is not the answer.
jk2addict on 2007-05-26T14:22:22
That's not exactly true inThere's no reason that any of those things should have an Is-A relationship. You need a cart that contains other distinct objects,.NET. The Cart whould returns a strongly type collection of CartItems, not a mishmash of Object that then have to be inspect just to see what they are. And I don't understand that statement about no reason for IS-A. A CartItem IS a part...period. 100% percent of the time. You can't buy anything that's not a part...but I digress... Well sure, you could do: And quite a few other variations. But that's just a messy API imho, an messy akward API just because they don't believe in MI (or Mixins). Having different items in a cart (GiftCert, Part) share the same interface sounds good, but then I have to write an Interface for it, and implement that in two places.. why bother? That's what inheritance is for. A GiftCert IS a part, and inherits all of the parts functionality. Why would I not want to use inheritance for that? A CartItem IS a part with some extra/altered functionality. So, we should never use base in perl then? There are many ways to skin the same cat, and they're not all wrong. MY point isCartItem.Part
CartGiftCert(Inherits CartItem).Part
or
CartItem.Part
CartItem.GiftCert(Inherits Part)
or even
Part
GiftCert(Inherits Part)
CartItem.Part
CartItem.GiftCert.NET shouldn't put up barriers because Interfaces don't always solve the same problems MI does. Re:Inheritance is not the answer.
gav on 2007-05-26T16:08:39
That's not exactly true in.NET. The Cart whould returns a strongly type collection of CartItems, not a mishmash of Object that then have to be inspect just to see what they are. It would make more sense to return a collection of objects that share similar interfaces, where these interfaces define the actions that you want to do with these objects.
Your cart could return a collection of objects that can be IOrderable, IShippable, etc, where these are characteristics of these objects.
Re:Inheritance is not the answer.
jk2addict on 2007-05-26T16:32:58
Right. I don't disagree with that statement as a solution.
Again, by using interfaces, each different type of object has to reimplement the same code the implement the interface. That's a waste of effort when inherts takes care of that problem. To avoid duplicating code for all different types of objects implementing IPart, they'de all have to use another class..which even more effort for no good reason.
We're not talking about unrelated objects in a collection ACTING like a part (via a common Interface), we're talking about all objects that ISA (are) a part implementing the same code.
There is a difference there. And for the sake of this topic, remember an Interface in.NET is not the (only) API of the class nor the code....it's just a interface contract describing behavour, not the code implementing it.
The use of Interfaces means you have to duplicate code to implement that interface somehow, somewhere making the solution more complicated that just using SI/MI.Re:Inheritance is not the answer.
brian_d_foy on 2007-06-05T15:37:45
Inheritance is only one way to look at that. An orderable item can be an object that contains a part along with an order description, coupon, etc. Those HAS-A relations, along with appropriate dispatching, don't need inheritance.
Like I said, inheritance is beat into people's heads, so they think in terms of it when in reality the world doesn't operate that way.Re:Inheritance is not the answer.
Aristotle on 2007-05-26T14:38:00
Thanks for saying that. I wanted to pipe up but couldn’t muster the energy to be coherent.
Inheritance is overrated. Polymorphism is the key; inheritance is not.