以下のシナリオでは、クラス定数がインスタンス変数に対して継承される方法に違いがある理由をよりよく理解したいと思います。
<?php
class ParentClass {
const TEST = "ONE";
protected $test = "ONE";
public function showTest(){
echo self::TEST;
echo $this->test;
}
}
class ChildClass extends ParentClass {
const TEST = "TWO";
protected $test = "TWO";
public function myTest(){
echo self::TEST;
echo $this->test;
}
}
$child = new ChildClass();
$child->myTest();
$child->showTest();
出力:
TWO
TWO
ONE
TWO
上記のコードでは、ChildClassにはshowTest()メソッドがないため、ParentClass showTest()メソッドが継承によって使用されます。結果は、メソッドがParentClassで実行されているため、TEST定数のParentClassバージョンが評価されているのに対し、継承を介してChildClassコンテキスト内で評価されているため、ChildClassメンバー変数$ testが評価されています。
私はドキュメントを読みましたが、このニュアンスについての言及を見ることはできません。誰かが私のために光を当てることができますか?
self::
継承を意識せず、常に実行されているクラスを参照します。php5.3+を使用している場合は、static::TEST
as static::
は継承を認識します。
違いは、static::
は「遅延静的バインディング」を使用します。詳細はこちらをご覧ください:
http://php.net/manual/en/language.oop5.late-static-bindings.php
これが私が書いた簡単なテストスクリプトです。
<?php
class One
{
const TEST = "test1";
function test() { echo static::TEST; }
}
class Two extends One
{
const TEST = "test2";
}
$c = new Two();
$c->test();
output
test2
PHPでは、selfは、呼び出されたメソッドまたはプロパティが定義されているクラスを指します。したがって、あなたの場合、self
でChildClass
を呼び出しているため、そのクラスの変数を使用します。次に、self
でParentClass
を使用するため、そのクラスの変数を参照します。
子クラスで親クラスのconst
をオーバーライドする場合は、親クラスの次のコードをこれに合わせて調整します。
public function showTest(){
echo static::TEST;
echo $this->test;
}
static
キーワードに注意してください。これは「遅延静的バインディング」を使用します。これで、親クラスは子クラスのconstを呼び出します。