PHP5成员可见性
有人能给我解释一下,为什么可以在PHP中执行以下操作,但不能在C#或Java中执行:PHP5成员可见性,php,visibility,private,encapsulation,Php,Visibility,Private,Encapsulation,有人能给我解释一下,为什么可以在PHP中执行以下操作,但不能在C#或Java中执行: A类{ 受保护$a=‘你好!’; } B类扩展了A类{ 公共函数howdy(){ $created=newa(); echo$created->a;howdy()这在C#(以及Java中也是可能的) 基本上是这样的: 类A包含一个名为A的受保护成员,这意味着它在扩展A的类的范围内可见(在本例中为类B) B类扩展了a,因此它可以访问受保护的成员(在我们的例子中是a) 在C#和Java中也可以这样做。受保护意味着
A类{
受保护$a=‘你好!’;
}
B类扩展了A类{
公共函数howdy(){
$created=newa();
echo$created->a;howdy()这在C#(以及Java中也是可能的)
基本上是这样的:
- 类A包含一个名为
A
的受保护成员,这意味着它在扩展A的类的范围内可见(在本例中为类B)
- B类扩展了a,因此它可以访问受保护的成员(在我们的例子中是
a
)
在C#和Java中也可以这样做。
受保护
意味着变量可以从A的任何子类访问。B是A的子类,因此它可以访问变量。这里没有什么神奇之处。您链接到的页面有一个标题为:
相同类型的对象将有权访问彼此的私有成员和受保护成员,即使它们不是相同的实例。这是因为在这些对象中,特定于实现的详细信息已为人所知
如果你这样做,那就行不通了:
$b = new B();
echo $b->a;
在您的示例中,您不是直接从B()访问$a成员。您是从恰好从B()内部实例化的a()对象访问它。它不起作用的原因是,正如您所指定的,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);
这使您可以封装受保护的信息,但仍然可以跨实例使用它
这两种方法都有优点和缺点…我可能遗漏了一些东西,但为什么不可能呢?您正在从一个对象调用一个公共函数。该函数创建了一个对象(内部)它从它有权访问的对象中回显变量。问题是什么?为什么预期会出现致命错误?没有成员可见性错误。B
可以看到所有a
,即public
或protected
。询问为什么某些东西在Lang X中有效或无效,但在Lang Y中无效通常是毫无意义的。They是不同的语言,所以它们可能不同。在这种情况下,你的假设是错误的。所以这里没有问题。@Nanne这可能是可能的,但其他几种语言禁止它,这导致了我的困惑(例如)无论如何,我对这个决定背后的基本原因很感兴趣(这不是你早上喝咖啡时发明的那种东西)@Gordon我同意你的第一句话,但我的哪一个假设是错误的?我猜这是错误的,请看这是错误的。PHP在类级别上实现安全性,而不是在实例级别上。其他语言在实例级别上实现安全性。两者都有优点和缺点…我猜不是。看,是的,但这一决定背后是什么?为什么会有人发明这种规则并将其添加到语言规范中?我当然理解PHP
设计者有权做他们想做的事情,但这种行为与其他语言中的类似行为不同,这可能有一些强烈的原因。
$b = new B();
echo $b->a;
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);