3 ms·
I think inheritance basically _is_ composition plus self-recursion. You get into trouble because of the self-recursion. Any time a base class method calls anot
by gwillen 14y ago
I think inheritance basically _is_ composition plus self-recursion.
You get into trouble because of the self-recursion. Any time a base class method calls another base class method, that call is part of the class's interface, because when you extend the class, the call will be redirected to the subclass' method.
But how many base classes have documentation for every self-call that can be redirected in such a manner?
See e.g. the "hashtable with plurals" example:
http://norvig.com/java-iaq.html#super http://norvig.com/java-iaq.html#super
- georgeorwell 14y agoMy understanding is that composition can be changed dynamically whereas inheritance cannot. It has always seemed to me like composition is more flexible. To give concrete examples: using composition, if instance A has a B, then at runtime you can replace the pointer to the B with a pointer to a C such that now A has a C. You basically change the type of A by changing where messages get sent / delegated. With inheritance, you'd have B is an A and C is an A, and the relationships here are static unless you start messing around with reflection and dynamic class loading and stuff. The tradeoff for the flexibility of composition is more verbose code, I think.
- deleted 14y ago[deleted]
- seanmcdirmid 14y agoDynamic inheritance is not unthinkable, I've used it in my languages before (or see research languages like Cecil). Of course, you can do this easily in dynamic languages like ruby.
- jrochkind1 14y agoActually, can you really do dynamic inheritance in ruby? I don't _think_ so. There are ways to apply inheritance dynamically at runtime of course (including with module mix-ins, which are basically just inheritance even though ruby pretends it isn't), but I don't think you can _undo_ inheritance at runtime. You can easily simulate dynamic inheritance in ruby.... with composition, using delegate-like patterns.
- draegtun 14y agobut I don't think you can _undo_ inheritance at runtime I'd be surprised if you couldn't do it in Ruby. You certainly can do it in Perl because it uses a package (class) variable called @ISA for it's inheritance lookup. And because package variables are dynamically scoped you can do this: { # remove everything except father from inheritance local @Some::Class:ISA = $Some::Class::ISA[-1]; $some_object->foo; # finds father foo() only } $some_object->foo; # runs first foo() found in inheritance
- bunderbunder 14y ago> You get into trouble because of the self-recursion. Which is why (savvy) object-oriented programmers have largely moved on to interface polymorphism. Inheritance polymorphism has its uses, which is why there hasn't been a whole lot of effort to rally behind languages that lack it, but the general consensus is that you should really only use inheritance when inheritance is what you really want to use. Unfortunately it's true that there's a whole lot of OO code out there that was written before people learned this lesson. And OO's popularity with pragmatists combined with its relative lack of popularity with academics means that a lot of code doesn't reflect lessons related to the pitfalls of inheritance polymorphism that academics figured out a very long time ago, such as the Liskov Substitution Principle.