この例を見て、示されている出力に注目してください。
<?php
class Mommy
{
protected static $_data = "Mommy Data";
public static function init( $data )
{
static::$_data = $data;
}
public static function showData()
{
echo static::$_data . "<br>";
}
}
class Brother extends Mommy
{
}
class Sister extends Mommy
{
}
Brother::init( "Brother Data" );
Sister::init( "Sister Data" );
Brother::showData(); // Outputs: Sister Data
Sister::showData(); // Outputs: Sister Data
?>
私の理解では、staticキーワードを使用すると子クラスが参照されますが、子クラスにない場合は常に親クラスに魔法のように適用されるようです。(これは、PHPにとって一種の危険な動作です。詳細については、以下で説明します。)
私がこれをやりたい理由について、私は次の2つのことを念頭に置いています。
- すべての子クラスのすべてのプロパティを定義する冗長性は必要ありません。
- プロパティを親クラスのデフォルトとして定義し、子クラスの定義で必要に応じてこれらのプロパティをオーバーライドできるようにしたい。子クラスは、デフォルトが意図されている場合は常にプロパティを除外する必要があります。そのため、上記の例では子クラスのプロパティを定義していません。
ただし、実行時に(initメソッドを介して)プロパティをオーバーライドする場合は、親クラスに対してプロパティをオーバーライドします。その時点から、以前に初期化された子クラス(Brotherの場合のように)が予期せず変更されます。
明らかに、これは、子クラス内で明示的に定義されていない場合は常に静的プロパティの独自のコピーを持たない子クラスの結果ですが、エラーをスローする代わりに、静的の動作を切り替えて親にアクセスします。したがって、親クラスが子クラス定義内に表示されることなく、子クラスに属するプロパティを動的に作成できる方法はありますか?このようにして、子クラスは静的プロパティの独自のコピーを持つことができ、staticキーワードはそれを適切に参照でき、親プロパティのデフォルトを考慮に入れるように記述できます。
それとも、良い、悪い、または醜い他の解決策がありますか?