PHP类成员的可见性和继承解释

5

考虑以下代码片段:

Class A {

    private $a = 'foo';

    public function F() {
        return $this->a;
    }

}

Class B extends A {

    private $a = 'bar';

}

echo (new B)->F();

结果是foo。php以这种方式工作已成定局,但我想知道为什么。如果在父类方法F()的声明中使用伪变量$this,它将引用对象上下文。因此,当我调用子类继承的方法F()时,$this变量表示B的当前实例,其中包含private $a = 'bar',对吗?
更新 感谢AbraCadaver的回复。 还有一个情况我不太清楚:如果$this变量在调用F()时是B的一个对象,那么它如何访问父类的私有成员? 我理解正确吗,父类方法实现中的$this类似于:
  public function F(B $obj) {
    return $obj->a;
}

因此,解释器从父类检查属性的可见性,在私有范围的情况下,将B $obj替换为A $obj


2
你想要 protected: 声明为 protected 的成员只能在类内部以及继承和父类中访问。 声明为 private 的成员只能被定义该成员的类访问。 http://php.net/manual/en/language.oop5.visibility.php - AbraCadaver
问题不在于使用protected。问题在于为什么PHP会忽略子类中定义的private变量。 - u_mulder
1
@u_mulder:子类无法覆盖私有属性。因此,如果您想让它正常工作,那么确实关乎protected。 - AbraCadaver
@u_mulder 忽略了在子类中定义的私有变量吗?由于F()是公共的,所以B类可以调用它。F()仅仅返回其所属类的私有成员的值。 - MonkeyZeus
@AbraCadaver,我看了你的回答并且很满意,谢谢) - u_mulder
1个回答

1

来自PHP: Visibility

声明为protected的成员只能在类本身及其继承和父类中访问。声明为private的成员只能由定义该成员的类访问。

在您的示例中,无论对象是类B的还是其他类的,类A都不能访问另一个类的私有属性。

此外,如果B有一个受保护的属性,它也无法覆盖类A的属性,因为它是私有的。

您的示例和以下示例都将返回foo:

Class A {

    private $a = 'foo';

    public function F() {
        return $this->a;
    }
}

Class B extends A {

    protected $a = 'bar';

    public function F() {
        return parent::F();
    }
}    
echo (new B)->F();

然而,如果类 A 也是 protected,那么它可以被类 B 覆盖,并且类 A 可以访问类 B 中的属性。
产生结果为 bar
Class A {

    protected $a = 'foo';

    public function F() {
        return $this->a;
    }
}

Class B extends A {

    protected $a = 'bar';

    public function F() {
        return parent::F();
    }
}
echo (new B)->F();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接