Search code examples
phpoopinheritanceprivate-methodslate-static-binding

Inheritance of a private method and Late Static Binding in php


So I've been reading official PHP documentation on Late Static Bindings and came across a confusing example:

<?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
?>

The output of the example:

success!
success!
success!


Fatal error:  Call to private method C::foo() from context 'A' in /tmp/test.php on line 9

Can someone please explain why the private method foo() gets copied to B? As far as I know only public and protected properties get copied to child class. What am I missing?


Solution

  • Maybe the comment "foo() will be copied to B" is a bit confusing or interpreted incorrectly. foo() is still private to A and can only be accessed from methods within A.

    ie. In the example if you try to execute$b->foo() its will still fail as expected.

    This is as I explained the example to myself and maybe will be helpful for others:

    Considering class B.

    $b->test() is able to access foo() as a public member of A.

    $this->foo() also succeeds within $b->test()

    $static::foo() succeeds because it is calling the version of foo() defined in A, from test() which is also defined in A. No scoping conflict.

    Considering class B.

    When foo() is overridden in class C, $c->test() of course is still accessible as a public member if A.

    and within $c->test() $this->foo() is accessible as a private member of A. - all good.

    BUT $static::foo() is now trying the access from A, the version of foo() defined in class C and so fails because it is private in C. - as per the error message.