Bug: Can't inherit abstract function

php.internals

Timm Friebe

21 years ago
Hi, the attached script produces: Fatal error: Can't inherit abstract function Drawable::draw() (previously declared abstract in Figure) in /usr/home/thekid/r.php on line 12 which is wrong because I am not inheriting anything but implementing an interface. The problem is that both zend_do_inheritance() *and* zend_do_implement_interface() use (merge_checker_func_t) do_inherit_method_check. Want me to open a bug report? - Timm

Timm Friebe

21 years ago
On Sat, 2004-10-09 at 15:26, Timm Friebe wrote:
> Hi, > the attached script produces:
[...Error message...] - if (parent->common.fn_flags & ZEND_ACC_ABSTRACT + if (!(parent->common.scope->ce_flags & ZEND_ACC_INTERFACE) + && parent->common.fn_flags & ZEND_ACC_ABSTRACT fixes the problem. - Ti "likes to talk to himself" mm

Andi Gutmans

21 years ago
What do you expect to happen? BTW, I see an additional problem. You aren't supposed to be able to use access modifiers such as public/abstract in an interface definition. This is something we have to fix. It should be: interface Drawable { function draw(); } Andi At 03:26 PM 10/9/2004 +0200, Timm Friebe wrote:

Jochem Maas

21 years ago
Andi Gutmans wrote:
> What do you expect to happen? > BTW, I see an additional problem. You aren't supposed to be able to use > access modifiers such as public/abstract in an interface definition. > This is something we have to fix. > It should be: > interface Drawable { > function draw(); > }
I would be very grateful if you could explain the logic behind not being able to define public/protected/private/static access modifiers for interface methods (obviously they are abstract by definition). AFAICS (not that far I admit!) not being able to define public/protected/private/static for interface methods removes a lot of the power of interfaces (in terms of being able to define specifics) tia, jochem

Wez Furlong

21 years ago
An interface is a *public* contract by definition; PPP specifiers just don't make sense there. Neither does static, since interfaces are instance based. --Wez. On Tue, 12 Oct 2004 09:34:00 +0200, Jochem Maas <jochem@iamjochem.com> wrote:

Jochem Maas

21 years ago
Wez Furlong wrote:
> An interface is a *public* contract by definition; PPP specifiers just > don't make sense there.
out of curiosity: would that be a definition at the PHP level (i.e. decided by php-devs) or is that definition more widely acknowledged (for want of a better word) (e.g. php-devs used the definition as used in C). anyway...thanks for knowledge-boost!
> > Neither does static, since interfaces are instance based.
where as the argument for PPP is wholly understandable, I can't see the logic in saying that interfaces are per-definition instance based. It is the class that implements the interface, but assuming that indeed interface should be instance based then would it not be correct to assume that interface implementation should only be checked if and when a class is initialized (i.e. so a class is used _only_ statically any interfaces it implements should be ignored), as per the following example (which only works if the 'abstract' is uncommented): <?php interface Foo { function foofoo(); } /* abstract */ class Bar implements Foo { public static function barbar() { echo "bar bar black sheep"; } } Bar::barbar(); ?> I can understand that interfaces more naturally lean towards use with instances rather than static classes - but it seems to me that forcing that is a case of telling users how they must program (I have always had the impression that PHP tried never to force a particular way of doing things) - not that its a big deal, because in the end a non-static method can be called statically if the user/programmer wishes (and then its his problem to make sure the method in question can handle being called that way, i.e. no refs to $this). Anyway, thanks very much for taking the time to broaden (at least) my knowledge of PHP. rgds, jochem

Andi Gutmans

21 years ago
At 02:46 PM 10/12/2004 +0200, Jochem Maas wrote:
>Wez Furlong wrote: > >>An interface is a *public* contract by definition; PPP specifiers just >>don't make sense there. > >out of curiosity: >would that be a definition at the PHP level (i.e. decided by php-devs) or >is that definition more widely acknowledged (for want of a better word) >(e.g. php-devs used the definition as used in C). > >anyway...thanks for knowledge-boost!
This is widely accepted practice. We just have to enforce it in the engine now.
>>Neither does static, since interfaces are instance based. > >where as the argument for PPP is wholly understandable, I can't see the >logic in saying that interfaces are per-definition instance based. It is >the class that implements the interface, but assuming that indeed >interface should be instance based then would it not be correct to assume >that interface implementation should only be checked if and when a class >is initialized (i.e. so a class is used _only_ statically any interfaces >it implements should be ignored), as per the following example (which only >works if the 'abstract' is uncommented): > ><?php > >interface Foo { function foofoo(); } > >/* abstract */ class Bar implements Foo >{ > public static function barbar() > { > echo "bar bar black sheep"; > } >} > >Bar::barbar(); > >?> > >I can understand that interfaces more naturally lean towards use with >instances rather than static classes - but it seems to me that forcing >that is a case of telling users how they must program (I have always had >the impression that PHP tried never to force a particular way of doing >things) - not that its a big deal, because in the end a non-static method >can be called statically if the user/programmer wishes (and then its his >problem to make sure the method in question can handle being called that >way, i.e. no refs to $this). > >Anyway, thanks very much for taking the time to broaden (at least) my >knowledge of PHP.
I tend to agree with Wez here. Interfaces mainly exist so that you can have more instanceof relationships for objects than just one (OK that's an oversimplification but I think it's very much down to earth). That said, there could be instances where it might be useful (such as a Singleton interface) but I don't think it's worth adding such a feature for edge cases. I am very much for simplicity. Andi

Wez Furlong

21 years ago
Interfaces describe how to talk to objects (or endpoints, if you're in to RPC) and so always have an instance (or handle) to talk to. Since static methods have no instance, they have no meaning in the context of interfaces--there is nothing to talk to. IMO. I'm +1 for simplicity here :-) --Wez. On Tue, 12 Oct 2004 14:47:46 -0700, Andi Gutmans <andi@zend.com> wrote:

Timm Friebe

21 years ago
On Tue, 2004-10-12 at 00:09, Andi Gutmans wrote:
> What do you expect to happen?
I expected it to work: Either give me a compile error ("You idiot! Why are you using method modifiers in an interface?") or not complain and let me code improper OO. The problem is the the confusing message. Btw, there was a thread about this quite a while ago ("[PHP-DEV] protected interface methods", http://zend.com/lists/php-dev/200307/thrd5.html). The conclusion was, I guess, that interface methods should always be public. - Timm

Andi Gutmans

21 years ago
Yeah this is definitely going to be fixed (partially fixed already in CVS) where you'll get a "You idiot" message if you try and use access modifiers :) I thought there was another bug you pointed out in your code but I might be wrong. Can't remember. Thanks, Andi At 10:07 PM 10/13/2004 +0200, Timm Friebe wrote: