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

Reply via email to