关于php:私有方法覆盖和可见性

Private method overriding and visibility

我很难理解以下代码的输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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();

输出:

1
2
Foo::testPublic
Bar::testPrivate

类foo重写testpublic()和testprivate(),并继承test()。当我调用test()时,有一个显式的指令envolving$这个伪变量,所以在我创建了$myfoo实例之后,test()函数的最终调用将是$myfoo->testpublic()和$myfoo->testprivate()。第一个输出如我所料,因为我将testpublic()方法覆盖到echo foo::testpublic。但是第二个输出对我来说毫无意义。如果我超越了testpprivate()方法,为什么是bar::testpprivate?另外,根据定义,父类的私有方法也不会被继承!这毫无意义。为什么要调用父方法????


代码的问题在于方法Bar::testPrivateprivate,因此它不能被子类重写。对于初学者,我建议您阅读php中的可见性-http://www.php.net/manual/en/language.oop5.visibility.php。在这里,您将了解到只有publicprotected类成员方法/属性可以被重写,而private类成员方法/属性不能被重写。

作为一个好例子,尝试将Bar::testPrivate方法的可见性更改为public或protected,而不更改示例代码中的任何其他内容。现在尝试运行测试。发生什么事了?这是:

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

大问题是:"为什么?"你现在用一个私人的Foo:testPrivate覆盖了Bar::testPrivate。这个新的私有方法超出了Bar::test的范围,因为私有类成员只对当前类可见,而不是父类/子类!

因此,正如您所看到的,OOP为类成员提供了一定数量的封装,如果您不花时间去理解它,这会非常令人困惑。