PHP5成员可见性

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中也可以这样做。受保护意味着

有人能给我解释一下,为什么可以在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的任何子类访问。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);