【问题标题】:Explanation of PHP class members visibility and inheritancePHP类成员可见性和继承的解释
【发布时间】:2015-07-14 19:26:27
【问题描述】:

考虑以下 sn-p:

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 变量时,表示Bprivate $a = 'bar' 的当前实例,不是吗?

更新 感谢 AbraCadaver 的回复。 一种情况我还不清楚:如果$this 变量在调用F() 期间是B 的对象,它如何访问父级的私有成员? 我是否正确理解父方法实现中的$this 类似于:

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

因此解释器检查父类的属性可见性,如果是私有范围,它会用B $obj 替换A $obj

【问题讨论】:

  • 你想要protected声明为protected的成员只能在类本身内以及被继承类和父类访问。 声明为私有的成员只能被访问由定义成员的类。 php.net/manual/en/language.oop5.visibility.php
  • 问题不是关于使用protected。问题是为什么 php 会忽略子类中定义的 private 变量。
  • @u_mulder:因为子类不能覆盖私有属性。所以是的,如果你想让它工作,它就是受保护的。
  • @u_mulder ignores private variable defined in a child class? F() 是公开的,所以 B 类可以调用它。 F() 只是返回它的类的私有成员的值。
  • @AbraCadaver 我阅读了您的回答并对它感到满意,谢谢)

标签: php


【解决方案1】:

来自PHP: Visibility

成员声明 protected 只能在类本身中访问,并且可以通过 继承类和父类。声明为私有的成员只能是 由定义成员的类访问。

在您的示例中,无论对象属于 B 类,A 类都无法访问另一个类的 private 属性。

另外,如果B 有一个受保护的属性,则不能覆盖类A 属性,因为它是private

您的示例和以下示例均产生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();

【讨论】:

    猜你喜欢
    • 2012-09-26
    • 2011-03-03
    • 2012-10-14
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 2013-06-23
    • 1970-01-01
    • 2020-02-07
    相关资源
    最近更新 更多