PHP从子上下文中将受保护的方法调用为public

时间:2014-12-22 18:34:57

标签: php class oop inheritance

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

<?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调用“test1()”而是从Test3上下文。所以这意味着“Test3”是一个全新的实例,它基本上不暴露任何方法。从我的角度来看,此代码适用于2个完全不同的2个对象实例

即便是IDE(PHPStorm)也说没问题。

任何线索?

2 个答案:

答案 0 :(得分:1)

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

class Foo {

    private $field;

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

}

对于受保护的成员,如果您正在使用和使用任何子类等,您将有权访问。

答案 1 :(得分:1)

当前类和任何子类(即扩展该类的任何类)都可以访问受保护的变量。

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

如果您将methodTest1()从protected更改为private,则Test2和Test3将无法访问它。

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