4

親クラスで変数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()によってアクセスされた関数に対して表示されないのはなぜですか。

4

4 に答える 4

3

スコープ解決演算子::は、自明ではない方法で動作する場合があります。定数または変数に適用すると、常に静的に解決されます。

ただし、関数に適用する場合、呼び出し先の実行コンテキストは呼び出し元コードの実行コンテキストに依存します。コンテキストは変更されません。

たとえば、これは警告なしで正常に機能します。

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->必要があります。

于 2013-02-14T09:34:35.307 に答える
1

これは、関数はオーバーライド可能であり(したがって、同じ名前の古いバージョンが共存する)、プロパティはオーバーライドできないためです(宣言は単に相互に上書きし、プロパティは子孫クラスで再宣言しないでください)。$this->プロパティが静的でない場合、および静的である場合は、常にプロパティの唯一のインスタンスにアクセスしself::ます。(プロパティが複数の祖先クラスで宣言されている場合でも、データフィールドは1つしかないため、「その他」または「以前の」を参照することはできません。)

于 2013-02-14T09:21:25.730 に答える
0

E_STRICTがアクティブ化されていない場合、エラーは発生しません。そうでない場合は、次のようになります。

厳格な基準:非静的メソッドparent :: SampleMethod()は静的に呼び出されるべきではありません...

于 2013-02-14T09:24:42.623 に答える
0

self::$UserName親を使用する代わりに、selfキーワードを使用して属性(定義されている場所)を使用してアクセスできます。子クラスでその値に到達したい場合(オーバーライドするため)、final::$UserName(後期静的バインディングと呼ばれる)を介してアクセスできます。

于 2013-02-14T09:30:29.913 に答える