クラス定数とプロパティのオーバーライド


98

以下のシナリオで、クラス定数がインスタンス変数と継承される方法に違いがある理由をよりよく理解したいと思います。

<?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が評価されていることを示しています。

私はドキュメントを読みましたが、このニュアンスについての言及は見られないようです。誰か私に光を当てることはできますか?


WTF?定数オーバーライド!?こんなことしないで!絶対に!
qwert_ukg 2016

2
@qwert_ukg確かに。誰かがそれをPHPの開発者に伝えるべきです。または、少なくとも許可しfinalます...
ルーク・サウザック'18

1
一定のオーバーライドを行う場合でも、十分に優れたユースケースがあります:]
Arziel

回答:


193

self::継承を意識したものではなく、常にそれがで実行されているクラスを参照します。あなたが試すかもしれない+あなたがPHP5.3を使用している場合static::TESTstatic::継承を意識しています。

違いは、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();

出力

test2

22
+言及についてstatic::
Jason McCreary、2012年

驚くばかり。説明とレイトスタティックバインディングに関する追加情報を提供していただきありがとうございます(これについてはまだ説明していません)。
Tom Auger、

3
test()は静的メソッドではないので$this::TEST、PHP5.3 +で使用しないのはなぜですか?
Xenos、2014年

こんにちは@Xenos-この例の目的は、クラス1で実行されているインスタンスレベルのコードがクラス2から静的な値を取得していることを示すことでした。self :: TESTは「test1」を返しますが、static :: TESTは予期された「test2」を返します-返信ありがとうございます。
David Farrell 2014年

こんにちは@DavidFarrell-はい、self::/のstatic::違いはわかりましたが、static::代わりに$this::(ではないself::)を使用する理由がわかりません。間に差がある$this::static::(の間に1があるのでstatic::/ $this::とはself::)?
Xenos 2014年

16

PHPでは、selfは呼び出されたメソッドまたはプロパティが定義されているクラスを指します。だからあなたの場合には、あなたが呼んでいるself中でChildClass、それはそのクラスからの変数を使用していますので、。次に、で使用selfするParentClassため、そのクラスの変数を参照します。

それでも子クラスでconst親クラスのをオーバーライドする場合は、親クラスの次のコードをこれに合わせます。

public function showTest(){
    echo static::TEST;
    echo $this->test;
}

staticキーワードに注意してください。これは「レイトスタティックバインディング」を使用しています。これで、親クラスは子クラスのconstを呼び出します。


プロ。静的::作られた代わりに、自己の抽象化での仕事::
BłażejKrzakala
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.