0

Php manual for the late static bindings states, in the example of static usage in non-static context, that foo() will be copied to B? Is method inheritance copying with scope of the original function being maintained?

<?php
class A {
    private function foo() {
        echo "success!\n";
    }
    public function test() {
        $this->foo();
        static::foo();
    }
}

class B extends A {
   /* foo() will be copied to B, hence its scope will still be A and
    * the call be successful */
}

class C extends A {
    private function foo() {
        /* original method is replaced; the scope of the new one is C */
    }
}

$b = new B();
$b->test();
$c = new C();
$c->test();   //fails 
AlexBor
  • 151
  • 2
  • 12

1 Answers1

0

As far as I can say, this is a problem of scope. When a child class does not override a parent's class method and you call said method via the child class, you will be in the parent class's scope and have access to private methods of the parent class. If you implement a test() method in the child class, you will have that scope when you call it and will not be able to access private methods of the parent class.

I would say that 'copy' is not a fitting term for what's happening because the parent methods are not copied, they are just available in the child class, given the right scope. That is, they don't take the scope of the child class, but keep their own. They are only accessible in the child class if set to protected (or public) or if you call private methods with the parent's scope (as described in your example).

More information from your linke here: Strange behavior when overriding private methods

The official documentation does not explain it explicitly, but I could find this:

Private methods of a parent class are not accessible to a child class. As a result, child classes may reimplement a private method themselves without regard for normal inheritance rules.

Johannes
  • 11
  • 3
  • 1
    How foo() is being copied if it's a private method? – AlexBor Dec 27 '22 at 12:43
  • It isnt copied into B or C. When foo() is called , the actual scope is A, because B doesn't overwrite the method test() . And since it's A, you have access to private methods in this scope. If B had the method test(), which would call foo() from B (with Bscope) , you would not have access. Does that answer your question? – Johannes Dec 27 '22 at 12:51
  • But the comment, from the documentation, explicitly says copied. That's what confuses me. I also found this answer: https://stackoverflow.com/questions/3756609/strange-behavior-when-overriding-private-methods#answer-3756879 – AlexBor Dec 27 '22 at 12:55
  • 1
    You are right, I did not use the correct terminology. As your linked posts states, there are two different mechanisms here. The first one is "copying" or however you want to call it, that is just terminology. The important thing is that the original scope is maintained. Only if you overwrite a method, you change the scope. (And lose access to private properties and methods in the parent.) – Johannes Dec 27 '22 at 12:58
  • And is that mechanism explained anywhere in the documentation? Or is there any article? I would like to have a reference. – AlexBor Dec 27 '22 at 13:02
  • 1
    I get you, I hate it when things seem so unclear and there seems to be no clear explanation in the official documentation. My explanation and the one from the thread you posted are mostly observations from how the code behaves. The best I can find is this: "Private methods of a parent class are not accessible to a child class. As a result, child classes may reimplement a private method themselves without regard for normal inheritance rules." From https://www.php.net/manual/en/language.oop5.inheritance.php Let me know if you find anything more. – Johannes Dec 27 '22 at 13:12