I'm pretty new to this list, and I'm not actively partaking in the development of PHP [yet] (i'm learning though ;), and I figured I might voice my opinion as an average PHP user (2 years or so, started with php3). Feel free to ignore me. :)
I've been following this thread for the past few days and honestly, so far, this is the most obvious and best solution I've seen. I've done some limited development with Java, C++ and Objective-C and I have to say that, for what PHP is, it's OOP model is perfectly fine the way it is: simple. Andi's proposal wins my vote because it performs exactly the way it looks. The idea of accessing methods from a class based on their inherited/aggregated class's name seems like a bit too much. ($obj->AggregatedObject::method() really doesn't appeal to me) Aside from this functionality, the only thing I suppose I'd like to see eventually would be the ability to declare class variables and methods as private. Just my 2 cents worth. - Gabriel Andi Gutmans wrote: > I still prefer to keep PHP a relatively easy to learn, simple yet > powerful language. > I think this is a huge overkill and prefer going with something like I > proposed. > Anyway the inheritance debates have been going on for years and I > doubt we'll solve all possible scenarios for the first time in > programming language history. Also historically the languages which do > try and solve lots of scenarios end up having extremely complex > mechanisms to do so. > I'll sum up my proposal again. > Support the following: > class MyClass extends MyParent aggregates Timer, FooBar > { > } > > $obj = new MyClass; // Creates $obj->Timer and $obj->FooBar > $obj->method(); // Searches MyClass, MyParent if not found tries to > call the method on $obj->Timer followed by $obj->FooBar > > If you want to access an aggregated object directly you can do: > $obj->Timer->method(); > > Got to go to bed now ;) > > Andi > > At 23:49 10/04/2002 +0300, Lauri Liinat wrote: > >> some thoughts concerning member name collisions: >> >> (i will also demonstrate a common shortcoming that i personally >> consider a design flaw that exists both in C++ and in Java - it sure >> would be good to avoid the same flaw in PHP - even if MI doesn't >> get into ZE2, keep this in mind for the future) >> >> simply put, the multiple interface paradigm says that a class can provide >> an unlimited number of interfaces for already-existing and / or >> future clients >> to operate on. an interface is a contract and it is preferably >> immutable - >> once defined, it is not a good practice to change it. additions and >> changes >> can be accommodated by creating new interfaces. this assures >> consistency - >> you are less likely to break something that relies on a contract if >> it's final. >> but it seems that there is one thing some language designers have >> overlooked: >> two methods with identical signatures (identical names) may have a >> totally different >> meaning in different interfaces, yet it should be possible to >> multiply implement >> both of those in one class. to achieve this, the class implementation >> has to know >> from which interface that ambiguos method was called from. as far as >> i know, >> this is impossible to accomplish in C++ as well as in Java (correct >> me if i'm wrong). >> >> let me demonstrate (C++, with virtual destructors omitted for >> simplicity): >> >> // implementation of an animated athlete running, >> // so that the result is both an athlete and an animation. >> // note that stopping (pausing) the animation is different from >> // stopping the athlete from running... >> >> class IAnimation { // the animation interface >> public: >> virtual void run() = 0; >> virtual void stop() = 0; >> }; >> >> class IAthlete { // the athlete interface >> public: >> virtual void run() = 0; >> virtual void stop() = 0; >> }; >> >> // so far so good... >> class CAthlete: public IAthlete, public IAnimation { >> public: >> virtual void run() { // now what? >> >> indeed, now what? there's no way to tell which interface we were >> being cast up to when run() was called... yet as long as the Virtual >> Method Table mechanism is concerned, it would actually be possible >> to override such ambiguos methods multiply so that they would depend >> on the upcast used - in case of non-virtual multiple inheritance as >> in the >> example above the number of VTBL's equals the number of base classes - >> the VTBL of the derived class is shared with the first base class and >> the rest base classes get one VTBL each. so it would be technically >> possible to allow language constructs such as: >> >> class CAthlete: public IAthlete, public IAnimation { >> public: >> virtual void run() {}; // shared between derived class and first base >> virtual void IAnimation::run() {}; // called when upcast to second base >> >> in case of virtual inheritance it would even be possible to differentiate >> between all three possible upcasts. however, sadly, C++ does not >> allow to explicitly differentiate overrides in different VTBL's. a >> similar >> equivalent seems to be missing from Java, too, if i'm not horribly >> mistaken... >> >> the effect of this flaw is that developers have to keep track on >> interface >> method names of all interfaces concurrently and manually avoid conflicts. >> this is, of course, a big heavy rock on shoulders. all of this also >> applies >> when multiply inheriting implementation, but i chose interfaces so that >> my example would make sense in Java. >> >> in PHP we would, of course, only find use for inheriting implementations, >> not interfaces. i suggest the following syntax for resolving ambiguities: >> >> class A { >> function foo() {} >> } >> >> class B { >> function foo() {} >> } >> >> class MI extends A, B { >> function foo() {} // *must* exist, throw compiler fatal otherwise >> function A::foo() {} // may exist, up to the programmer >> function B::foo() {} // may exist, up to the programmer >> } >> >> $mi = new MI(); >> $a = (A)$mi; // explicit upcast >> $b = (B)$mi; // explicit upcast >> >> $mi->foo(); // calls MI::foo() >> $a->foo(); // calls MI::A::foo() if exists, MI::foo() otherwise >> $b->foo(); // calls MI::B::foo() if exists, MI::foo() otherwise >> >> since all objects are passed by reference in ZE2, this would >> work as expected, that is, quite reasonably well. but what if >> someone inherits from MI? let me list the possibilities: >> >> class X extends MI { >> function foo() {} >> function MI::foo() {} >> function MI::A::foo() {} >> function MI::B::foo() {} >> } >> >> anybody can see that this syntax would bring *polymorphism* to >> a new level and open up neverbeforeseen doors in sense of code reuse. >> why should we give up on MI and keep all those doors closed? >> i see no harm caused by such syntax to neither compatibility with >> single inheritance nor to novice / non-expert PHP programmers - >> if they simply don't use features they do not comprehend then PHP >> looks like plain-vanilla good-old single-inheritance PHP as they've >> always known it. but for the wonderers out there, we would give >> a whole new world to explore... and finally, the only certain way >> to find out whether a product is successful is to put it on the market... >> >> any comments / corrections are most welcome, >> >> lauri >> >> >> >> -- >> PHP Development Mailing List <http://www.php.net/> >> To unsubscribe, visit: http://www.php.net/unsub.php > > > -- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php