Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
350 views
in Technique[技术] by (71.8m points)

php - Private method overriding and visibility

I'm having a hard time trying to understand the output of the following code:

class Bar 
{
    public function test() {
        $this->testPublic();
        $this->testPrivate();
    }

    public function testPublic() {
        echo "Bar::testPublic
";
    }

    private function testPrivate() {
        echo "Bar::testPrivate
";
    }
}

class Foo extends Bar 
{
    public function testPublic() {
        echo "Foo::testPublic
";
    }

    private function testPrivate() {
        echo "Foo::testPrivate
";
    }
}

$myFoo = new foo();
$myFoo->test();

Output:

Foo::testPublic
Bar::testPrivate 

Class Foo overrides testPublic() and testPrivate(), and inherits test(). When I call test(), there is an explicit instruction envolving $this pseudo variable, so after I created $myFoo instance, the final calls of test() function would be $myFoo->testPublic() and $myFoo->testPrivate(). The first output is as I expected, since I overrode testPublic() method to echo Foo::testPublic. But the second output makes no sense to me. Why is it Bar::testPrivate if I overrode testPrivate() method? Also the private method from parent class wouldn't be inherited anyway, by definition! It makes no sense. Why is the parent method the one being called???

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem with your code is that the method Bar::testPrivate is private, therefore it cannot be overridden by child classes. For starters, I recommend that you read up on visibility in PHP - http://www.php.net/manual/en/language.oop5.visibility.php. There you will learn that only public and protected class member methods/properties can be overridden, private ones cannot.

As a good example, try changing the visibility of the Bar::testPrivate method to either public or protected, without altering anything else in your example code. Now try and run your tests. What happens? This:

PHP Fatal error: Access level to Foo::testPrivate() must be protected (as in class Bar) or weaker

The big question is: "why?". Well, you have now overridden Bar::testPrivate with a private Foo:testPrivate. This new private method is out of scope for Bar::test, because private class members are visible to their current class only, NOT the parent/child classes!

Therefore, as you can see, OOP provides a certain amount of encapsulation for class members, and it can be quite confusing if you don't take the time to understand it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...