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

I am using php 5.3, and yes, there is an error for this, but some people think that this is not an error, and it makes me think.

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

This causes an error. Should inherit private methods be ignored ?!

'The declaration of B :: bobo () must be compatible with A :: bobo ()'

+6
inheritance oop php
source share
5 answers

Please note that the error report is slightly disabled, as PHP will log this message at any time when you have the E_STRICT error E_STRICT (or, more recently, regardless of your error level, provided that you have installed a custom error handler).

PHP visibility rules clearly demonstrate that the child does not have the ability to see their parental private members, and I doubt that this is all surprising to everyone. If the child does not see his parental methods, I do not understand how he can fulfill his definitions.

I personally believe that a mistake marked as fictitious without explaining why it was not a real flaw (since it is not obvious, and I could not find mention of this in the documentation), this is a little wrong, but yes. As an aside, I believe that line 2669 in zend_compile.c should look like this:

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

... that would avoid the error when the parent method was marked as private. Considering that you always have the opportunity not to register E_STRICT , although in fact this does not negatively affect me, I believe this is not very important. I definitely don't see how this could have been intentional, but I'm not a PHP developer either.

+5
source share

I think there are two possibilities. Either this is an error, or the documentation for PHP.net/manual is incorrect. Here are three sections of the PHP manual. First about inheritance:

Object Inheritance

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

For example, when you extend a class, the subclass inherits all public and protected methods from the parent class. If the class does not override these methods, they will retain their original functionality.

It is useful for defining both abstract functionality and allowing the introduction of additional functionality in similar objects without the need to redefine all common functionality.

And on abstract classes:

Class abstraction

PHP 5 introduces abstract classes and methods. It is not possible to instantiate a class that has been defined as abstract. Any class containing at least one abstract method must also be abstract. Methods defined as abstract simply declare they cannot define an implementation.

When inheriting from an abstract class, all methods marked as abstract in the parent class declaration must be determined by the child; in addition, these methods must be definable with the same (or less limited) visibility. For example, if an abstract method is defined as protected, the implementation of the function should be defined as either protected or open, but not closed.

Finally interfaces

Object interfaces

Object interfaces allow you to create code that determines which methods the class should implement, without specifying how these methods are processed.

Interfaces are defined using the interface keyword, just like a standard class, but without any methods that define their contents.

All methods declared in the interface must be publicly available, this is the nature of the interface.

Suffice it to say: the documentation does not mention the inheritance of private methods. If there is a connection between the signatures of the parent and child methods, then this is not documented, and the error report should at least show someone that the documentation needs updating (if the decision on this behavior is intentional). And if there weren’t a relationship, then this is a real mistake.

What is my opinion ...

+2
source share

There is no error in the error report when removing the interface. This makes it more "weird" because the interface is just empty.

+1
source share

I think this is a design solution to the language. Java developers decided that this should be possible.

0
source share

Private methods, of course, should not be ignored by inheritance, for example, consider a template template template in which you can override the function behavior in a derived class, but the parent class can still call this function

 public class Parent { public final function doThings() { $this->initialize(); $this->customStuff(); $this->cleanup(); } private final function initialize() { // initialize processing } private final function cleanup() { // cleanup processing } private function customStuff() { // parent specific processing } } public class Derived extends Parent { private function customStuff() { parent::customStuff(); // + derived class specific processing } } 

The calling doThings method on the Derived instance of the class will handle the parent specificity, but due to the ability to override private methods, you can still use the extension point provided by the customStuff method of the non-standard parent class.

EDIT: also the signature of the PHP method consists only of the name of the method, since you can define a method that takes null parameters and still calls it with several parameters. The function can then access the arguments using the func_get_args function.

0
source share

All Articles