PHP 从子上下文调用受保护的方法作为公共方法


PHP Call protected method as public from child context

我刚刚编写了以下代码(期望它失败),我真的不明白为什么它会像这样:

<?php
abstract class Test1 {
    protected function methodTest1() {}
}
class Test2 extends Test1{
    public function methodTest2() {
        $test3 = new Test3();
        $test3->methodTest1();
    }
}
class Test3 extends Test1 {
}
$test2 = new Test2();
$test2->methodTest2();

预期结果:致命错误,因为我调用类的"受保护"成员,就像它是公共成员一样

实际结果:...工程

我错过了什么吗?

我认为这与 Test2 扩展 Test1 以便它可以访问它的事实有关,但在这种情况下没有意义,因为我不是从 Test2 而是从 Test3 上下文调用"test1()"。所以这意味着"Test3"是一个全新的实例,基本上不公开任何方法。从我的角度来看,这段代码适用于 2 个对象的 2 个完全不同的实例

甚至IDE(PHPStorm)也说没问题。

有什么线索吗?

这是

正确的行为。可见性与类有关,它不局限于对象(类实例)。所以这是有道理的:

class Foo {
    private $field;
    public function method(Foo $fooInstance) {
        //have access to everything from $fooInstance
        //cause I'm already in that class
        $fooInstance->field;
    }
}

对于受保护的成员,如果您正在使用任何子类等,则可以访问。

受保护的变量既可以在当前类中访问,也可以在任何子类(即扩展该类的任何类)中访问。

假设您在 Test2 和 Test3 中都扩展了 Test1,则在这两种情况下都可以访问受保护的函数 methodTest1()。

如果将 methodTest1() 从受保护更改为私有,则 Test2 和 Test3 将无法访问它。

从 Test2 中调用 Test3 的事实无关紧要 - 两个类都扩展了 Test1,因此两个类都可以访问 methodTest1()。