PHP5会员可见性

时间:2012-05-18 13:56:00

标签: php visibility private encapsulation

有人可以解释一下,为什么可以在PHP中执行以下操作,但是,例如,不是在C#或Java中:

Class A {
    protected $a = 'Howdy!';
}

Class B extends A {
    public function howdy() {
        $created = new A();
        echo $created->a; <----- This is legal due to per-class visibility
    }
}

$b = new B();
echo $b->howdy();  <----- Hence, no fatal error here

这种行为似乎是here,指定的,但我无法理解这个 背后的根本原因(在我看来,不能简单地实现{{1}可见性而不是per-class,而没有充分的理由)。

5 个答案:

答案 0 :(得分:2)

在C#(以及Java)中也可以这样做。

class A                               // declare new class type B
{
   protected string a = "Howdy!";     // that has a protected member called `a`
}

class B : A                           // declare new type B which extends type A
{
   public void howdy()
   {
       A created = new A();
       Console.WriteLine(created.a);  // no problem accessing a b/c B extends A
   }
}


B bInst = new B();                    // create a new instance of type B
bInst.howdy();                        // invoke it's public method howdy()

基本上是这样的:

  • A类包含一个名为a protected 成员,这意味着它在扩展A的类的范围内可见(在我们的例子中是B类)
  • B类扩展a以便它可以访问受保护的成员(在我们的例子中是a

答案 1 :(得分:2)

也可以同时使用C#和Java。 protected表示可以从A的任何子类访问该变量.B是A的子类,因此它可以访问该变量。这里没有魔力。

答案 2 :(得分:2)

您关联的网页上有一个标题为"Visibility from other objects"的部分,其中指出:

  

相同类型的对象可以访问彼此私有和受保护的成员,即使它们不是同一个实例。这是因为在这些对象内部已经知道实现特定的细节。

答案 3 :(得分:2)

它不起作用的原因是,如您所指定的,PHP在类级别实现访问控制,其他语言使用实例级方法。

为什么有用?它允许您的类在其自身的其他实例上运行,而不会暴露其私有数据。我们来看一个简单的值对象示例:

class Int {
    protected $value = 0;
    public function __construct($value) {
        $this->value = (int) $value;
    }
    public function add(Int $new) {
        return new Int($new->value + $this->value);
    }
}

$a = new Int(1);
$b = new Int(2);
$c = $a->add($b);

这使您可以保护封装的受保护信息,但仍然可以跨实例使用它...

两种方法都有利弊......

答案 4 :(得分:0)

如果你这样做了就行不通了:

$b = new B();
echo $b->a;

在您的示例中,您不是直接从B()访问$ a成员。您正在从A()对象访问它,该对象碰巧已从B()内部实例化。