PHP方法范围绑定

Ner*_*ero 11 php oop object

我对父子层次结构中PHP调用方法的方式感到困惑.这是代码

class A {
        private function foo() {
            echo "A!";
        }
        public function test() {
            $this->foo();
        }
 }

class C extends A {
       public function foo() {
            echo 'C!';
       }
}

$c = new C();
$c->test();  
Run Code Online (Sandbox Code Playgroud)

输出是A!

考虑另一个例子,但只改变A类中的foo()方法可见性是公开的.

class A {
        public function foo() {
            echo "A!";
        }
        public function test() {
            $this->foo();
        }
 }

 class C extends A {
        public function foo() {
            echo 'C!';
        }
 }

 $c = new C();
 $c->test();  
Run Code Online (Sandbox Code Playgroud)

这个输出是C!

欢迎任何解释.

bis*_*hop 8

规则:privatefinal方法的对象上总是被称为直接,没有咨询的覆盖表.

此规则被引入引擎:

/* Check if this calls a known method on $this */
if (opline->op1_type == IS_UNUSED && opline->op2_type == IS_CONST &&
        CG(active_class_entry) && zend_is_scope_known()) {
    zend_string *lcname = Z_STR_P(CT_CONSTANT(opline->op2) + 1);
    fbc = zend_hash_find_ptr(&CG(active_class_entry)->function_table, lcname);

    /* We only know the exact method that is being called if it is either private or final.
     * Otherwise an overriding method in a child class may be called. */
    if (fbc && !(fbc->common.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_FINAL))) {
        fbc = NULL;
    }
}
Run Code Online (Sandbox Code Playgroud)

"你为什么问?答案是:因为它是如何运作的.在语言设计中,这被称为"名称隐藏",并且由语言来指定名称隐藏的工作方式.以C++为例.它具有定义明确且复杂的名称隐藏规则.PHP有自己的规则.它们与C++不同.但它们是PHP独有的.这只是你必须记住的语言.

不过,我承认文档可以更好地拼写出来.