有人可以解释一下,为什么可以在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
,而没有充分的理由)。
答案 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
的 protected 成员,这意味着它在扩展A的类的范围内可见(在我们的例子中是B类)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()内部实例化。