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