@Vlad
I skipped your post because I was arguing against use of abstract classes, and you asked me if that means I want PHP's handling of abstract classes to be more strict? Your question doesn't make sense. Virtual methods are a feature of abstract classes, which I am arguing against.
@vlad
sure they could remove 'abstract' as soon as they implement prototypical inheritance

That would also allow removal of 'public' vs 'private', etc.
@Christopher
4 ways to define a class in javascript? I know of only one, 'function'.
@christopher
What does implementation language mean then? To me it means the language in which you are typing your implementation details, it implies code is what implements your customer's specification. How are the names of methods & classes not implementation details of your program?
@christopher
Regarding parent::foo() I never brought up parent, you did. Not sure what that's about. My argument was that when adding a method to a class, I must navigate it's chain of super classes making sure I'm not choosing a name that will unintentionally override a previously defined method on one of those super classes. Instead of just adding a method I may have to visit several different classes & read over their possibly length method lists. This takes from seconds to minutes or more each time I want to extract out a new method, or add a new method. There's a huge benefit to being able to name a method without it breaking something due to the name you chose.
With composition I can add new methods all day long without worry of my new method nulling out some previously defined behavior. It allows more flexible method naming.
@christopher
robot cannot inherit animal because robots aren't organisms! They shouldn't breathe() and sleep()!!! You're going to print_r() your object and get loads of unrelated information. That's a big code smell.
Inheritance = take it or leave 100% of all defined methods & variables. No in-between.
Composition = take what you need only, no more no less.
Jonah Bron wrote:I'm just reading here, I don't think I'm in a position to jump in,

but...
josh wrote:Here the compiler does nothing to warn you that you're calling a method on Bar instead of Foo, so I'm not sure what your repeated rebuttal about calling "parent::" is about. If a method is overridden, you definitely need to be conscious of that.
If it does something different, wouldn't you just not override it? Or create a new Foo instead?
Yep, which entails the extra steps of reading over the super class' method list, and actually thinking of an alternative name for it once you find out it does conflict with a previously defined method. Its the same as global variables in the sense that w/ globals a variable can overwrite another variable's value if they used the same name. With abstract classes a method can overwrite a previously defined method. The problem is of the same nature but not as insidious as globals.
The only benefit of abstract classes is you type "$this->foo()" instead of "$this->bar->foo()", and a few less delegating methods (which can be good or bad, because it reduces the number of "seams" as defined by Michael Feathers). If we had prototypical inheritance there would be literally no benefit to having abstract classes anymore.
@Christopher
Basically the only reason to use abstract classes is its less verbose, and only in some situations. That's the same argument people give for why global variables, or singletons are a good idea. To me, making my program harder to re-factor doesn't justify a couple less keystrokes anymore than using a singleton would. Since abstract classes DO have limits and composition does not, there is a high likely hood you're going to need to change it from an abstract class to a composite object down the line anyways. That's the same reason we use not to use singletons, because it hinders certain changes (by making refactoring a lot harder). If you find out in a week you did need composition, you will very likely have to go change ALL of the code on ALL of a class' super-classes.