I do not know how to write a heading in this case, but what is the actual question?

See the code:

<?php class People { private function status() {return __METHOD__;} public function Sleep(){ echo $this->status().'<br />'; } } class Programmer extends People { private function status() {return __METHOD__;} } $obj = new Programmer(); $obj->Sleep(); ?> 

At the exit, the following People::status

In this example, we change access modifiers to protected (or the public result will be the same as that of protected )

 <?php class People { protected function status() {return __METHOD__;} public function Sleep(){ echo $this->status().'<br />'; } } class Programmer extends People { protected function status() {return __METHOD__;} } $obj = new Programmer(); $obj->Sleep(); ?> 

The output is the following Programmer::status

How does this mechanism work? It is not clear why with private he does not give the same result as with protected . I didn’t see anything like this on php.net (there is something briefly mentioned about closed methods, but this information is not enough to understand)

  • On php.net, everything about this situation is (read in order): - scope ; - late static binding - uorypm
  • @uorypm I read it all several times, and I understand how the scope and later static binding work, there’s another problem ... take a closer look - MaximPro
  • So tell me what the problem is, if not in your lack of understanding of the scope? - uorypm

2 answers 2

I will make your comment in the form of an answer. The documentation about your situation says:

  • Area of ​​visibility
  • Late static binding

     <?php class People { private function status() { return __METHOD__; } public function sleep() { echo static::status().'<br />'; } } class Programmer extends People { private function status() { return __METHOD__; } } $obj = new Programmer(); $obj->sleep(); 

Pay particular attention to the error description:

FATAL ERROR Call to private method Programmer :: status () from context 'People' on line number 12

  • I got a little stuck, I realized my mistake (that the funny thing was not at all where it should be) =) - MaximPro

Private (private) methods are available only from inside the class. When you create a new private method Programmer::status() in the heir, you do not override the parent method, but do write a new function with the same name as the function in the parent, but only in a different scope. Because you have not redefined the Sleep() method in the heir, then when you make a call:

 $obj = new Programmer(); $obj->Sleep(); 

Programmer::Sleep() is executed as parent::Sleep() . And in the parent scope, the status() method is defined and should return People :: status. Those. if you would redefine the method Programmer::Sleep() , the result would be the same as changing access modifiers, because in this case the code would call the Sleep() method from its scope.

 <?php class Programmer extends People { private function status() {return __METHOD__;} public function Sleep(){ echo $this->status().'<br />'; } } 

At the output we get: Programmer::status .

Do not declare closed methods whose implementation you want to change in the heirs. Especially for this there is a protected access modifier, such methods will be available for the entire inheritance hierarchy.

  • I understood that the private method in the programmer did not override (the concept of overriding for private something does not exist) I did not understand one thing: how did it happen that the scope in the heir was different, that is, how the Sleep method from the parent class did not see the private method that I announced? - MaximPro
  • because the call to Programmer::Sleep() in your case is equivalent to a call from the class Programmer parent::Sleep() , the scope of parent:: is the class People, respectively, it is quite natural that eventually the call to People::status() occurs. Once again: the scope of the People class is the People class, not the Programmer; if you have not redefined the Sleep () method in the Programmer, then call parent::Sleep() ( People::Sleep() ), for which in $this->status() $ this is a pointer to an object of the class People. - Igor Karpenko
  • Maybe it is worth noting the answer as a solution?) Everything was chewed on in detail. - Hlogeon