Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is this a php bug: subclasses must declare private methods with the same signature as in parent class

I am using php 5.3, and yes, there is a bug open for that, but some think this is not a bug, and this makes me wonder.

abstract class A{
   private function bobo(array $in){
     //do something
   }
}

class B extends A{
   private function bobo($shmoo,$shmaa){
     //do something
   }
}

This throws an error. Shouldn't inheritance ignore private methods?!

'Declaration of B::bobo() should be compatible with that of A::bobo()'

like image 749
Itay Moav -Malimovka Avatar asked Jul 15 '10 18:07

Itay Moav -Malimovka


3 Answers

Note that the bug report is slightly off, as PHP will log this message any time you have an error level of E_STRICT (or, more recently, regardless of your error level provided that you've set a custom error handler).

PHP's visibility rules clearly demonstrate that a child lacks the ability to see its parent's private members, which I doubt is all that surprising to anyone. If the child can't see its parent's methods, I don't understand how it can have a duty to obey their definitions.

I personally think that the bug being marked as bogus without any explanation of why it wasn't a real flaw (since it's non-obvious and I couldn't find any mention of it in the documentation) is a bit wrong, but yeah. That aside, I'm of the opinion line 2669 in zend_compile.c should actually read as follows:

} else if (child->prototype &&
    (EG(error_reporting) & E_STRICT || EG(user_error_handler))) {

...which would avoid the error popping up when the parent's method was marked private. Given that you always have the option not logging E_STRICT though, and it doesn't really negatively impact anything, I suppose it's not really a big deal. I definitely don't see how it could have been intentional, but I'm not a PHP engine developer either.

like image 185
Tim Stone Avatar answered Oct 15 '22 00:10

Tim Stone


I think there are two possibilities here. Either it's a bug or the documentation on PHP.net/manual is incorrect. Here are three sections of the PHP manual. First on inheritance:

Object Inheritance

Inheritance is a well-established programming principle, and PHP makes use of this principle in its object model. This principle will affect the way many classes and objects relate to one another.

For example, when you extend a class, the subclass inherits all of the public and protected methods from the parent class. Unless a class overrides those methods, they will retain their original functionality.

This is useful for defining and abstracting functionality, and permits the implementation of additional functionality in similar objects without the need to reimplement all of the shared functionality.

And on abstract classes:

Class Abstraction

PHP 5 introduces abstract classes and methods. It is not allowed to create an instance of a class that has been defined as abstract. Any class that contains at least one abstract method must also be abstract. Methods defined as abstract simply declare the method's signature they cannot define the implementation.

When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child; additionally, these methods must be defined with the same (or a less restricted) visibility. For example, if the abstract method is defined as protected, the function implementation must be defined as either protected or public, but not private.

Finally, interfaces

Object Interfaces

Object interfaces allow you to create code which specifies which methods a class must implement, without having to define how these methods are handled.

Interfaces are defined using the interface keyword, in the same way as a standard class, but without any of the methods having their contents defined.

All methods declared in an interface must be public, this is the nature of an interface.

Suffice it to say: there is nothing in the documentation that mentions inheritance of private methods. If there is a relationship between the parent and child method signatures, then it is not documented and the bug report should at least show someone that the documentation needs to be updated (if the decision to have this behavior is intentional). And if there was not supposed to be a relationship, then well, it's a real bug.

That's my opinion...

like image 37
TCCV Avatar answered Oct 15 '22 01:10

TCCV


In the bug report when you remove the interface there isn't an error. That makes it "more" strange behavior because the interface is just empty.

like image 38
Sander Avatar answered Oct 15 '22 00:10

Sander