【问题标题】:How to access Variable in parent class using parent:: method如何使用 parent:: 方法访问父类中的变量
【发布时间】:2013-02-14 09:10:25
【问题描述】:

我在父类中有受保护的变量 UserId。我将在我的子类中扩展该变量,如下所示

class Main
{
  protected $UserId          = "151";
  protected static $UserName = "Madhavan";      

  protected function SampleMethod()
  {
    print "This is Sample Method";
  } 
}


class SubMain extends Main
{   
  function __construct()
  {    
    print parent::SampleMethod();

    print "User Id is ".$this->UserId."<br/>";          
    print parent::$UserName;
    print "User Id is ".parent::$UserId."<br/>";            
  }
}

当我使用 $this->UserId 打印正常。但是当我使用 Parent::$UserId 时显示错误

致命错误:访问未声明的静态属性:Main::$UserName

为什么它没有显示我通过 parent::SampleMethod() 访问的函数,因为该函数不是静态的。

【问题讨论】:

标签: php


【解决方案1】:

范围解析运算符:: 有时会以不明显的方式运行。当应用于常量或变量时,它总是以静态方式解析。

但是,当应用于函数时,被调用者的执行上下文取决于调用者代码的执行上下文;上下文没有改变。

例如,这可以正常工作而没有任何警告:

class Test
{
  private $a = 123;

  public function __construct()
  {
    Test::test();
    self::test();
  }

  public function test()
  {
    echo $this->a;
  }
}

new Test();

调用self::test()Test::test() 都以非静态方式运行,因为__construct() 被非静态调用并且您引用的是同一个类。

要引用任何实例变量,例如上例中的$a,需要使用$this-&gt;

【讨论】:

    【解决方案2】:

    这是因为函数是可覆盖的(因此旧版本的同名共存)而属性不是(声明只是相互覆盖,并且不应在后代类中重新声明属性)。如果它不是静态的,您总是使用$this-&gt; 访问属性的唯一实例,如果它是静态的,则使用self::。 (如果在多个祖先类中声明了一个属性,则仍然只存在一个数据字段,因此您不能引用任何“其他”或“以前的”。)

    【讨论】:

    • 你也可以这样想:所有的上层类声明的名称(函数和属性)都在一个类中累积。您可以像在此类中声明它们一样使用它们中的任何一个。只有一个例外:当您想要访问以前的版本时,它们已经被重新声明该名称所隐藏。在这些情况下,您可以使用静态调用来命名包含您要使用的先前版本的类。 parent 只是命名直接祖先的快捷方式,因为这是最常见的用例。
    【解决方案3】:

    如果 E_STRICT 未激活,您将不会收到错误消息,否则您将收到如下内容:

    严格标准:非静态方法 parent::SampleMethod() 不应在...中静态调用

    【讨论】:

    • 这不会发生,因为parent:: 并不一定意味着静态上下文。
    【解决方案4】:

    您可以使用 self::$UserName 属性(定义它的位置)和 self 关键字来访问它,而不是使用 parent。如果您想在子类中达到它的值(因为覆盖它),可以通过final::$UserName 访问它(称为后期静态绑定)

    【讨论】:

      猜你喜欢
      • 2012-07-04
      • 1970-01-01
      • 1970-01-01
      • 2020-02-13
      • 1970-01-01
      • 2018-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多